Pshivvy
Pshivvy

Reputation: 583

Promise is "pending" even with having ".then" chained, issues only occurs while using normal functions

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.

Upvotes: 1

Views: 595

Answers (2)

Gustavo Shigueo
Gustavo Shigueo

Reputation: 501

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

Upvotes: 1

codemonkey
codemonkey

Reputation: 7905

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();

Upvotes: 1

Related Questions