Home > Blockchain >  Async Await not returning value as expected
Async Await not returning value as expected

Time:01-21

I have a basic understanding of Async Await, but I seem to be missing something.

Refer to the code below. I have placed console.log lines throughout to trace the execution. I expect that each console.log should return the token in order. but 'Token1' and 'Token3' return 'undefined' while 'Token2' returns the actual token.

Questions:

  • Am I using Async await correctly?
  • Am I returning 'credentials.access_token' correctly?
async function GetAuthTokenAsync() {
  // Initialize the 2-legged OAuth2 client, set specific scopes and optionally set the `autoRefresh` parameter to true
  // if you want the token to auto refresh
  var autoRefresh = true; // or false

  var oAuth2TwoLegged = new ForgeSDK.AuthClientTwoLegged(
    FORGE_CLIENT_ID,
    FORGE_CLIENT_SECRET,
    ["data:read", "data:write"],
    autoRefresh
  );

  oAuth2TwoLegged.authenticate().then(
    function (credentials) {
      // The `credentials` object contains an access_token that is being used to call the endpoints.
      // In addition, this object is applied globally on the oAuth2TwoLegged client that you should use when calling secure endpoints.
      console.log("Token2: ", credentials.access_token);                 //RETURNS THE TOKEN
      return credentials.access_token;
      },
    function (err) {
      console.error(err);
    }
  );
}

async function Token() {
  const token = await GetAuthTokenAsync();
  console.log("Token1: ", token);                                        //RETURNS 'undefined'
  return token;
}

Token().then(AuthToken => console.log('Token3: ', AuthToken));           //RETURNS 'undefined'

CodePudding user response:

You're not quite using it properly. Every async function returns a Promise but if you don't have an explicit return statement, it will return a resolved promise with a value of undefined. That is why you see Token1 as undefined. Your GetAuthTokenAsync runs the call, but it doesn't await the result and doesn't return anything.

I have marked up your code to show what changes would be needed below.

async function GetAuthTokenAsync() {
  // Initialize the 2-legged OAuth2 client, set specific scopes and optionally set the `autoRefresh` parameter to true
  // if you want the token to auto refresh
  var autoRefresh = true; // or false

  var oAuth2TwoLegged = new ForgeSDK.AuthClientTwoLegged(
    FORGE_CLIENT_ID,
    FORGE_CLIENT_SECRET,
    ["data:read", "data:write"],
    autoRefresh
  );

  return oAuth2TwoLegged.authenticate().then(   // <---- Must return a promise
    function (credentials) {
      // The `credentials` object contains an access_token that is being used to call the endpoints.
      // In addition, this object is applied globally on the oAuth2TwoLegged client that you should use when calling secure endpoints.
      console.log("Token2: ", credentials.access_token);                 //RETURNS THE TOKEN
      return credentials.access_token;
      },
    function (err) {
      console.error(err);
    }
  );
}

async function Token() {
  const token = await GetAuthTokenAsync();
  console.log("Token1: ", token);                                        //RETURNS 'undefined'
  return token;
}

Token().then(AuthToken => console.log('Token3: ', AuthToken));

In addition using .then inside an async function is allowed but it makes it harder to read. It can be simplified like this:

async function GetAuthTokenAsync() {
  // Initialize the 2-legged OAuth2 client, set specific scopes and optionally set the `autoRefresh` parameter to true
  // if you want the token to auto refresh
  var autoRefresh = true; // or false

  var oAuth2TwoLegged = new ForgeSDK.AuthClientTwoLegged(
    FORGE_CLIENT_ID,
    FORGE_CLIENT_SECRET,
    ["data:read", "data:write"],
    autoRefresh
  );

  const credentials = await oAuth2TwoLegged.authenticate();
  console.log("Token2: ", credentials.access_token);                 
  //RETURNS THE TOKEN
  return credentials.access_token;
}

If you really want to catch & console.log the error inside of GetAuthTokenAsync then you can add a .catch() function but it's better to let the error get thrown up the stack usually.

CodePudding user response:

you have to do in this way

async function GetAuthTokenAsync() {
    // Initialize the 2-legged OAuth2 client, set specific scopes and optionally set the `autoRefresh` parameter to true
    // if you want the token to auto refresh
    var autoRefresh = true; // or false
  
    var oAuth2TwoLegged = new ForgeSDK.AuthClientTwoLegged(
      FORGE_CLIENT_ID,
      FORGE_CLIENT_SECRET,
      ["data:read", "data:write"],
      autoRefresh
    );
  
    // you need to await the token before you can use it
    const credentials = await oAuth2TwoLegged.authenticate()
    // .then(
    //   function (credentials) {
    //     // The `credentials` object contains an access_token that is being used to call the endpoints.
    //     // In addition, this object is applied globally on the oAuth2TwoLegged client that you should use when calling secure endpoints.
    //     console.log("Token2: ", credentials.access_token);                 //RETURNS THE TOKEN
    //     return credentials.access_token;
    //     },
    //   function (err) {
    //     console.error(err);
    //   }
    // );

    return credentials.access_token;
  }
  
  async function Token() {
    const token = await GetAuthTokenAsync();
    console.log("Token1: ", token);                                        //RETURNS 'undefined'
    return token;
  }
  
  Token().then(AuthToken => console.log('Token3: ', AuthToken)); 
  •  Tags:  
  • Related