Sona Shetty
Sona Shetty

Reputation: 1047

How to return values from a nested Axios call?

I am trying to perform the below steps:

Step 1: Make Axios call to check if record exists in database.
Step 2: If the record does not exit then make a POST API call to create data and return POST response.
Step 3: If the record already exists then return the response from Step 1

Step 1 and Step 2 works fine and I am able to return the value from createProfileByUserIDNew. When code block for Step 3 gets executed then createProfileByUserIDNew is not returning any value.

Can someone tell me what am I doing wrong?

async createProfileByUserIDNew(data, email) {
        const AuthStr = 'Bearer ' + getToken();
        const response = await axios
            .get(`${baseUrl}/buyer-profiles?user_email=${email}`, {
                headers: { Authorization: AuthStr },
            })
            .then((response) => {

                 //*****This block return proper value in the next then
                if (response.data.length === 0) {
                    return axios.post(`${baseUrl}/buyer-profiles`, data, {
                        headers: { Authorization: AuthStr },
                    });
                //~~~~~~~This block return proper value in the next then

                //*****This block does not return any value in the next then
                } else {
                    return response //Return response from first axios call
                }
                //*****This block does not return any value in the next then

            })
            .then((response) => {           
                return (response);  //Step 2 return the value but step 3 return undefined             
            })
            .catch((error) => console.log(JSON.stringify(error)));
}

Calling the above method:

const ret = createProfileByUserIDNew(
    data,
    user.email
);
ret.then(function (response) {
    console.log(response); //Setp 2 returns proper value but step 3 return undefined
    this.setState({ buyerProfileId: response.items.id });
});

Upvotes: 2

Views: 1925

Answers (2)

juliomalves
juliomalves

Reputation: 50348

That happens because when you simply do return response you're returning the response of the request, not a Promise. You should only chain the .then() when making the axios.post() call since that actually returns a Promise.

Also, if you want to use the createProfileByUserIDNew function the way you are currently you need to return the Promise from axios.get directly.

async createProfileByUserIDNew(data, email) {
    const AuthStr = 'Bearer ' + getToken();
    return axios.get(`${baseUrl}/buyer-profiles?user_email=${email}`, {
            headers: { Authorization: AuthStr },
        })
        .then((response) => {
            if (response.data.length === 0) {
                return axios.post(`${baseUrl}/buyer-profiles`, data, {
                        headers: { Authorization: AuthStr },
                    })
                    .then((response) => {           
                        return response;
                    });
            } else {
                return response;
            }
        })
        .catch((error) => console.log(JSON.stringify(error)));
}

Upvotes: 0

Brendan Bond
Brendan Bond

Reputation: 1890

Remember that async/await is "syntactic sugar" for the other promise syntax of chaining .then(), .catch(), and .finally(); in other words, it allows you to handle these types of asynchronous operations in code that appears more synchronous.

const createProfileByUserIDNew = async (data, email) => {
  const AuthStr = "Bearer " + getToken();

  try {
    // we're awaiting this response, so we don't need to chain a .then()
    // we could even destructure response into the objects we'll need later, 
    // i.e. const { data } = await axios.get(...)
    const response = await axios.get(
      `${baseUrl}/buyer-profiles?user_email=${email}`,
      {
        headers: { Authorization: AuthStr },
      }
    );
    if (response.data.length === 0) {
      // do the things we need to do when we don't get the data we want
      // once again, we don't have to chain a then() to this; you may
      // have heard that 'return await' is redundant and causes some 
      // problems, but since we're in a try/catch it's ok
      // see https://jakearchibald.com/2017/await-vs-return-vs-return-await/
      return await axios.post(`${baseUrl}/buyer-profiles`, data, {
        headers: { Authorization: AuthStr },
      });
    } else {
      // the user exists, so we'll do other things, like maybe return the 
      // original response or something
      return response;
    }
  } catch (error) {
    console.error("We hit a snag:", error);
  }
};

// now when we call this method (must be called from another async function), the same principles apply
const ret = await createProfileByUserIDNew(data, user.email);
console.log(ret);
This.setState({ buyerProfileId: ret.data.items.id });

Upvotes: 2

Related Questions