Francesca
Francesca

Reputation: 28148

How to properly implement async/await

I am new to using async/await - I am trying to return data from an API call and format/tidy it slightly.

I'm really struggling to work out how to make this work because of the asynchronous nature of the functions. I cannot get the promise to work without the browser simply falling over.

My first function calls the API and gets a response as JSON. I then store a subset of this data json.recommendations

function getRecs() {
    const requestUrl = `blahblah`;
    const options = {
        headers: {
            'Content-type': 'application/json',
            Accept: 'application/json',
        },
        method: 'GET',
    };

    fetch(requestUrl, options).then((res) => {
        if (res.ok) {
            return res.json();
        }
        throw new Error('Error!!??', res);
    }).then((json) => {
        return json.recommendations;
    });
}

My second function takes json.recommendations and does some tidying to remove unwanted data and return a new array of data, those that match my filter.

async function getInStockRecs() {
    const recs = await getRecs();
    if (recs !== undefined) {
      return recs.filter(function(rec){
          return rec.isInStock === true;
      });
    }
}

A third function formats the data further:

async function topThreeArray() {
    const inStockRecs = await getInStockRecs();
    const topThree =[];
    for (let i = 0; i < i <= 3; i++) {
        topThree.push(inStockRecs[0]);
    }
    return topThree;
}

By using await I intended each function to only run once the data has been returned properly from the previous. However running the above crashes the page and I cannot do anything to debug as it simply crashes. Where am I going wrong?

Upvotes: 2

Views: 53

Answers (1)

Lennholm
Lennholm

Reputation: 7480

You don't return anything in your getRecs() function (you only return in the callbacks to the fetch() call)

Since you're using async-await elsewhere, why not use that for the getRecs() function too?:

async function getRecs() {
  const requestUrl = `blahblah`;
  const options = {
    headers: {
        'Content-type': 'application/json',
        Accept: 'application/json',
    },
    method: 'GET',
  };

  const res = await fetch(requestUrl, options);
  if (res.ok) {
      return res.json().recommendations;
  }
  throw new Error('Error!!??', res);
}

Otherwise, you'd have to return the fetch() call itself:

return fetch(requestUrl, options).then((res) => {
  ...

The reason the browser crashes is because the condition in the for loop in topThreeArray() is weird (i < i <= 3) and results in an infinite loop.
Basically, i < i evaluates to false, which gets implicitly coerced into 0, so the condition effectively becomes 0 <= 3 which is always true.

Finally, I'd like to point out that you should carefully consider if async-await is appropriate in the first place when running in a browser as support for it is still very fragile and scetchy in browsers.

Upvotes: 2

Related Questions