0

I'm using axios to return API data in a React app. Based on this guidance, I created this function:

function axiosGet(itemid) {
    const promise = axios(withAuth({
        url: `${apiUrl}/items/?itemid=${itemid}`
    }))
    const dataPromise = promise.then((response) => response.data)
    return dataPromise
}

and this code to invoke it:

const getData = (theitemid) => {
    const itemdata = axiosGet(theitemid)
        .then(data => {
            console.log(data.length);  // correctly prints the value I want
            return data.length
        })
        .catch(err => console.log(err))

    console.log(itemdata) // at this point, itemdata is: Promise {<pending>}
    return itemdata
}

I want getData to return the resolved value returned from axiosGet.

But instead of being resolved, it's in pending status.

Is there some way I can hold off on returning itemdata until it is actually resolved?

Woodchuck
  • 3,869
  • 2
  • 39
  • 70

2 Answers2

0

you have two many options, you can return promise or await the result

const getData = async (theitemid) => {
    const itemdata = await axiosGet(theitemid)
        .then(data => {
            console.log(data.length);  // correctly prints the value I want
            return data.length
        })
        .catch(err => console.log(err))

    console.log(itemdata) // at this point, itemdata is: Promise {<pending>}
    return itemdata
}
Mina Fawzy
  • 20,852
  • 17
  • 133
  • 156
0

In your case, getData is basically the same thing as axiosGet, the fact that you went ahead and created getData to me is an indicator that your difficulty is with using functions that return promises.

Such functions are also called, asynchronous functions.

Do not despair, this is not an easy thing to grasp, especially for self-taught web developers in 2022.

I hope this code might help you wrap your head around what you want to do:

// setup 1: rename axiosGet to getData 
const getData = axiosGet;

// setup 2: define a function with the actions you want to 
//          execute on/with the data once it is available.
function actionOnData (data) {
    // replace this with what you want to do
    console.log(`I like this data: "${data}"`);
}

// option 1: use the "await" keyword
const myData = await getData(myIdentifier);
actionOnData(myData);

// option 2: use the original, callback-based syntax for promises
getData(myIdentifier).then(actionOnData);

In both cases, what will happen is that when your data is available, the actions in the actionOnData function will be executed.

I am aware that what you might be trying to do in your React application might not be as simple as the scenario I showed above.

For example:

  1. You might want something else, for example, another asynchronous operation, to commence before or after doing the stuff you want to do in actionOnData.
  2. You might want, in doing the stuff you want to do in actionOnData, to access and/or interact with other parts of your React application (for example, with component state).

In either case, more knowledge and experience with Promises will make a big difference in how you will be able to find your way around these situations.

My advice would be to use the async and await keywords because they create the abstraction of "linear execution" and hence they will help you get the job done until you are more comfortable with promises and how they work exactly without this added layer of syntactical sugar.

Until then, enjoy using your async and awaits!

PS: To add error handling to axiosGet use the following:

function axiosGet(itemid) {
    return axios(withAuth({
        url: `${apiUrl}/items/?itemid=${itemid}`
    }))
        .then(response => response.data)
        .catch(error => { console.error(`axios error: ${error}`) });
}
  • Should 'async' be used anywhere in the code here? – Woodchuck Nov 18 '22 at 21:29
  • Yes, you can only use `await` inside of a function that had been defined with the keyword `async`, this means that you would have to change the definition of the function from within you are using `await` for you to be able to use that keyword. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function – Orwa Diraneyya Nov 18 '22 at 21:48
  • I really appreciate the help. Unfortunately, I still don't get my data. The result I get from option 2 is: I like this data: "undefined" – Woodchuck Nov 22 '22 at 21:45
  • Try to add some error handling into axiosGet as shown in the edited answer. – Orwa Diraneyya Dec 04 '22 at 23:57