Async/Await not waiting for response, and returns Promise object

Viewed 9980

Using ES6, Classes, and Aync/Await...

The goal is to have an "Api" class that does async calls with fetch, and returns some data.... but even the basic foundation isn't working.

in the main js these snippet runs, which starts the chain of events:

let api = new Api();
let api_data = api.getLocation();

console.log(api_data);

getLocation method is the following, which would return some response/data. However, that data would theoretically be a fetch call to an API, which is "getTestVariable" for example that waits some time...

class Api {
  getLocation = async () => {
    var response = await this.getTestVariale();
    console.log(response);
    return response;
  }


  getTestVariale = () =>{
    setTimeout(function(){
      console.log("timeout done...");
      return "this is the test variable";
    },2000);
  }
 }

However, 1) the console.log(response) gives "undefined" because its not awaiting... and 2) back in the main js, api_data when logged, is some Promise object rather than the variable response

2 Answers

As the comment above states, setTimeout does not return a Promise, so getTestVariable has no return value.

Here's a slightly modified version of your code that will hopefully put you on the right track:

class Api {
  getLocation = async () => {
    var response = await this.getTestVariale();
    console.log(response);
    return response;
  }


  getTestVariale = () => {
      return new Promise((resolve, reject) => {
          if (thereIsError)
              reject(Error('Error message'));
          else 
              resolve({foo: 'bar'});
      }
  }
}

Drop a comment if I need to explain further I'd be happy to.

In getLocation you await for a value that will come from this.getTestVariable. In order for this to work this.getTestVariable must return a Promise; it can be done in two ways - making getTestVariable an async function or explicitly returning a Promise.

Since you're using setTimeout (which is not an async function) you're bound to use Promise. Here you go:

class Api {
  async getLocation() {
    return await this.getTestVariable();
  }

  getTestVariable() {
    return new Promise((res, rej) => {
      setTimeout(() => res('test'), 2000)
    });
  }
}

async function main() {
  let api = new Api;

  console.log('Trying to get the location...');
  console.log('Voila, here it is: ', await api.getLocation());
}

main();

Looks quite ugly but there's no way you can achieve it if you use set timeout.

The main point is in resolution of getTestVariable with value you want it to return.

Quite an important remark: you can mark getTestVariable as an async function, it will ad an extra Promise level, but you still will have the desired result.

Related