1

I am currently trying to use an API to get IP addresses for visitors. I am getting a "promise pending" message when using the following code:

function getIPAdd(){
  var ip = fetch('https://pro.ip-api.com/json/?key=KEY').then(response => response.json()).then(data => data);
  return ip;
}
var ipAdd = getIPAdd();
console.log(ipAdd);

I get this output:

Promise {<pending>}
   __proto__: Promise
   [[PromiseState]]: "fulfilled"
   [[PromiseResult]]: Object

This means that the promise is ebing fulfilled but for some reason, still is not completed?

While if I use the following code:

(function(){
   fetch('https://pro.ip-api.com/json/?key=KEY').then(response => response.json()).then(data => console.log(data));
 })();

I do not get any "promise pending" issues. I am guessing this is becasue it is due to the way console.log is used in the latter code sample but how can I fix the first code sample so I get my JSON output the way I need it.

Pshivvy
  • 573
  • 3
  • 12
  • 2
    Does this answer your question? [Why is my asynchronous function returning Promise { } instead of a value?](https://stackoverflow.com/questions/38884522/why-is-my-asynchronous-function-returning-promise-pending-instead-of-a-val) – Ivar Jan 27 '21 at 20:43
  • 1
    You have a timing problem. What you fail to realize is that the function inside `then` is only called after the fetch completes but `return ip` gets executed first before the function inside `then`. The `then` methon **is** how you are supposed to return a value – slebetman Jan 27 '21 at 20:44
  • 1
    You can just do `var ipadd = getIpAdd(); ipadd.then(console.log)` – slebetman Jan 27 '21 at 20:45
  • 1
    Or you can do `async function x () { var ipadd = await getIpAdd(); console.log(ipadd) } ; x()` – slebetman Jan 27 '21 at 20:45
  • Okay, that works! But how would I use this if I wanted the JSON value to be returned from the function itself? As in, without having to do all the extra ".then" outside the function – Pshivvy Jan 27 '21 at 20:48
  • 1
    If you don't want to use `.then`s you can use `await`, but that is only possible inside an `async` function. (And this async function itself will then return a Promise.) You can't fully synchronize asynchronous code. – Ivar Jan 27 '21 at 20:52
  • I got it. Thank you, I will use that then. – Pshivvy Jan 27 '21 at 20:56

2 Answers2

1

You need to resolve the promise that fetch returns. Something like this should work:

function getIPAdd(){
  var ip = fetch('https://pro.ip-api.com/json/?key=KEY').then(response => response.json());
  return ip;
}
var ipAdd = getIPAdd();
ipAdd.then(data => console.log(data));

Another way to do this is by using the await keyword. The only catch there is that you can only do so from an async function. So here is an example:

const getIP = () => fetch('https://pro.ip-api.com/json/?key=KEY').then(response => response.json())

const main = async () => {
  ip = await getIP();
  console.log(ip)
}

main();
codemonkey
  • 7,325
  • 5
  • 22
  • 36
1

This happens because at the time of your console.log the Promises haven't been resolved yet, in other words, console.log(ipAdd) runs before return ip. Fixing this with promises can get complicated, I recommend using the async/await and ES6+ syntax:

const getIPAdd = async () => {
  const response = await fetch('https://pro.ip-api.com/json/?key=KEY');
  const ip = await response.json();
  return ip;
}

const doStuffWithIP = async () => {
  const ipAdd = await getIpAdd()
  console.log(ipAdd)
  // Code to use IP address here
}

doStuffWithIP() // Don't forget to call the function
Gustavo Shigueo
  • 399
  • 3
  • 11