0

please check the below axios get request example to a random public api.

Intro

I would simply like to create a function which will execute get requests and return data, so I can store the returned data in a variable and use it in the UI I am building.

Currently the function returns Promise object and not data as expected.

I also noticed that returned promise object is printed before logged data response. This makes me think that for some reason return command doesn't await the resolution of the promise.

I can use any other library apart axios as well, but tried fetch which is giving me same results.

Furthermore, I tried executing correct code from other stackoverflow answers on this topic, but it gave me same results. Which leads me thinking my issue has something to do with my environment.

What I already tried

  • I looked into all answers on query "axios request returns undefined" and similar
  • I looked into all answers on query "get data from axios request" and similar
  • tried executing the code from browser using react
  • changing the function to synchronous, which instead of Promise object return undefined

My env:

  • System Version: macOS Monterey 12.4 (21F79)
  • Kernel Version: Darwin 21.5.0
  • Node@v18.7.0
  • axios@0.21.4
  • iterm@2

Example

The example can be executed by running node script.js.

// filename: script.js
const axios = require("axios");

async function fetchApi() {
    const getRequest = await axios.get("https://api.publicapis.org/entries")
      .then((response) => {
        console.log("logged response:", response.data.count);
        return response.data.count;
    })
};

const response = fetchApi();
console.log("returned response:", response);

// execute@bash: node script.js
// returned response: Promise { <pending> }
// logged response: 1425

My question

I would expect returned result and logged result to be the same.

Please help me troubleshoot this issue.

2 Answers2

0

It is impossible to return the data, because the data doesn't exist yet. Instead, you will need to return a promise. async functions automatically return promises, so you're part way there, but you currently aren't returning anything from your async function. I also recommend you don't mix async/await with .then as it will just cause confusion:

async function fetchApi() {
    const response = await axios.get("https://api.publicapis.org/entries")
    return response.data.count;
};

To access the eventual value of the promise, you will need to put your code in an async function and await the promise:

async function someFunction() {
  const count = await fetchApi();
  console.log(count);
}
Nicholas Tower
  • 72,740
  • 7
  • 86
  • 98
  • thanks @Nicholas, my aim is actually to use returned data in global context as a name for a button. So when I use your implementation and return value from someFunction it will still be a promise. I might be missing some major features of javascript and/or webdev as I am quite new to it. Also I tried without `async`, which will return undefined instead of promise. – Miha Majcen Aug 07 '22 at 18:05
  • Yeah, it's promises all the way down. It's not possible to return a value that doesn't exist yet. async/await is a tool to simplify working with promises, but you still must use promises. If `someFunction` isn't where you're using the value, then whatever function calls `someFunction` will need to await the promise that `someFunction` returns. And the function before that will need to await a promise too, etc. This continues all the way to the code that actually uses the value. – Nicholas Tower Aug 07 '22 at 18:10
  • ok thanks for all the answers. I finally managed to achieve it in react with using state and useEffect. Seems the issue was in me not understanding couple of javascript concepts... – Miha Majcen Aug 07 '22 at 19:12
0

Your fetchApi is an async function, which means it will return a Promise.

You should use either await or .then() syntax to execute your next actions after the Promise is resolved.

The only problem is that you can't use await syntax in your current implementation since you're using the result in the top level of your script file and not inside a function, Node didn't support top-level awaits in older versions.

So you should either use .then() syntax like this:

fetchApi().then( response => {
  console.log("returned response:", response)
};

or wrap your code inside a function if you want to use await syntax:

async function main() {
  const response = await fetchApi();
  console.log("returned response:", response);
}

main();

if you are using Node v14.8+ you can just use await inside a module:

const response = await fetchApi();
console.log("returned response:", response);
Positivity
  • 5,406
  • 6
  • 41
  • 61
  • thanks @Positivity. I can already achieve this with current code. The problem arises when I want to return data into global context - I would like to pass the value as a name for some button. Unfortunately the server is running older node. Is there a similar implementation for older versions of node? – Miha Majcen Aug 07 '22 at 18:08
  • @MihaMajcen No, I'm not aware of that, why don't you just return the Promise and wait for the resolution in your main script.. see https://stackoverflow.com/a/56262272/2543240 – Positivity Aug 07 '22 at 18:13
  • ok thanks for all the answers. I finally managed to achieve it in react with using state and useEffect. Seems the issue was in me not understanding couple of javascript concepts... – Miha Majcen Aug 07 '22 at 19:12