NSS
NSS

Reputation: 795

Using async-await not returning the values

I use the following code which works! I was able to fetch the data in the spread (then) , http200

Promise.all([
    axios({
      method: 'post',
      url: 'https://oauth2.-arch.mand.com/oauth2/token',
      data: qs.stringify({
        'grant_type': 'client_credentials'
      }, {
        'scope': 'run:crud'
      }),
      headers: {
        'Accept': 'application/json',
        'Authorization': 'Basic NTgwNjgtMDhhZTczOGNl',
        'Content-Type': 'application/x-www-form-urlencoded',
      }
    }),
    axios({
      method: 'post',
      url: 'https://oauth2.-arch.mand.com/oauth2/token',
      data: qs.stringify({
        'grant_type': 'client_credentials'
      }, {
        'scope': 'exe:crud'
      }),
      headers: {
        'Accept': 'application/json',
        'Authorization': 'Basic NTgwNjgtMDhhZTczOGNl',
        'Content-Type': 'application/x-www-form-urlencoded',
      }
    })
  ]).then(axios.spread((...responses: AxiosResponse[]) => {
      const aToken = responses[0];
      const bToken = responses[1];
    }).catch(function(error: any) {
      console.log("Error: " + error);
    });

Now I want to wrap it with async function which return two response (responses[0], responses[1] )

I’ve created this function

const FetchData = async (): Promise<{ run: string; app: string }> => {

let aToken:string;
let bToken:string;
Promise.all([
    axios({
      method: 'post',
      url: 'https://oauth2.-arch.mand.com/oauth2/token',
      data: qs.stringify({
        'grant_type': 'client_credentials'
      }, {
        'scope': 'run:crud'
      }),
      headers: {
        'Accept': 'application/json',
        'Authorization': 'Basic NTgwNjgtMDhhZTczOGNl',
        'Content-Type': 'application/x-www-form-urlencoded',
      }
    }),
    axios({
      method: 'post',
      url: 'https://oauth2.-arch.mand.com/oauth2/token',
      data: qs.stringify({
        'grant_type': 'client_credentials'
      }, {
        'scope': 'exe:crud'
      }),
      headers: {
        'Accept': 'application/json',
        'Authorization': 'Basic NTgwNjgtMDhhZTczOGNl',
        'Content-Type': 'application/x-www-form-urlencoded',
      }
    })
  ]).then(axios.spread((...responses: AxiosResponse[]) => {
      aToken = responses[0];
      bToken = responses[1];
    }).catch(function(error: any) {
      console.log("Error: " + error);
    });

// add this return 
return {
    run: aToken ,
    app: bToken
};

)}

Now I’ve created function to call it and get the tokens

async function main() {

    let val = await FetchData();
    console.log(val)


}

The problem is that I got empty value in the val property, while put a breakpoint inside main function I see that I got into the console, before I actually get the values from the ).then(axios.spread(( , Any idea how to adopt the code to return the value from the spread operator and then call to the console?

Upvotes: 1

Views: 806

Answers (3)

Yousaf
Yousaf

Reputation: 29282

You are not using async-await correctly. You need to await Promise.all. Once both promises are resolved, response data will be in a property named data inside each response object that you get from axios. If you need whole response object then you can destructure it

Here's an example

const FetchData = async (): Promise<{ run: string; app: string }> => {
    try {
        const [response1, response2] = await Promise.all([
            axios({
               ...
            }),
            axios({
               ...
            })
        ]);

        return {
          run: response1,
          app: response2
        };

   } catch (error) {
      console.log(error);
   }
};

Here's a demo that fetches data from 2 endpoints of jsonplaceholder api

Upvotes: 1

Piyush
Piyush

Reputation: 609

You need to change the position of your return statement:

Updated code with changes:

const FetchData = (): Promise<{ run: string; app: string }> => {

let aToken:string;
let bToken:string;
// Return the promise here

return Promise.all([
    axios({
      method: 'post',
      url: 'https://oauth2.-arch.mand.com/oauth2/token',
      data: qs.stringify({
        'grant_type': 'client_credentials'
      }, {
        'scope': 'run:crud'
      }),
      headers: {
        'Accept': 'application/json',
        'Authorization': 'Basic NTgwNjgtMDhhZTczOGNl',
        'Content-Type': 'application/x-www-form-urlencoded',
      }
    }),
    axios({
      method: 'post',
      url: 'https://oauth2.-arch.mand.com/oauth2/token',
      data: qs.stringify({
        'grant_type': 'client_credentials'
      }, {
        'scope': 'exe:crud'
      }),
      headers: {
        'Accept': 'application/json',
        'Authorization': 'Basic NTgwNjgtMDhhZTczOGNl',
        'Content-Type': 'application/x-www-form-urlencoded',
      }
    })
  ]).then(axios.spread((...responses: AxiosResponse[]) => {
      aToken = responses[0];
      bToken = responses[1];

      // This return is for getting the data once the promise is resolved either with then or await
      return {
         run: aToken ,
         app: bToken
      };
    }).catch(function(error: any) {
       console.log("Error: " + error);
       return error;
    });

)}

As you are returning the value before the promise is resolved so you are not getting any data. You need to return promise and inside then you need to return the required data, to get once the promise is resolved in invoking function.

Upvotes: 1

gengsong
gengsong

Reputation: 36

const res = await Promist.all([...])
return { run: res[0], app: res[1] }

Upvotes: 1

Related Questions