Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

async await fetch undefined. How to handle?

I am currently learning async await fetch and I've created the following example to help me learn.

The working example below:

  1. fetches three random json records from a Public API
  2. extracts the url from each return json
  3. creates three img elements
  4. appends three img elements to the document body.

Notice that promise2 has an intentionally wrong path set to force a http status 404.

How do I handle this error if it was to happen to any of the three promises?

// the big promise.
  async function getAsyncData() {

    try {

      // attempt to resolve 3 individual unrelated promises...
      let promise1  = await fetch('https://dummyimage.com/48x48/4caf50/ffffff.jpg&text=.jpg');
      let promise2  = await fetch('https://dummyimage.com/bad/url/here/48x48/e91e63/ffffff.png&text=.png');
      let promise3  = await fetch('https://dummyimage.com/48x48/00bcd4/ffffff.gif&text=.gif');

      // we create an html img element and set its src attribute to the thumbnailUrl...
      var img = document.createElement('img');
      img.src = promise1.url;
      // ...and add it to our html document body...
      document.body.append(img);

      // we create an html img element and set its src attribute to the thumbnailUrl...
      var img = document.createElement('img');
      img.src = promise2.url;
      // ...and add it to our html document body...
      document.body.append(img);

      // we create an html img element and set its src attribute to the thumbnailUrl...
      var img = document.createElement('img');
      img.src = promise3.url;
      // ...and add it to our html document body...
      document.body.append(img);

    } catch (error) {

      console.log('Try/Catch block error:', error);

    }

    // return {


    // }

  }

  getAsyncData();
like image 621
suchislife Avatar asked May 26 '20 17:05

suchislife


People also ask

How do I respond to await fetch?

When the request completes, the promise resolves to the response object. From the response object you can extract data in the format you need: JSON, raw text, Blob. Because fetch() returns a promise, you can simplify the code by using the async/await syntax: response = await fetch() .

Does fetch support async await?

Fetch using async/await syntaxFunctions are prepended by the keyword async , which enables the use of the keyword await inside them. Any process that returns a promise is prepended by the keyword await , which halts execution of the code below it until the promise is resolved or rejected.

Is async await better than fetch?

Fetch returns a promise which resolves to the request data or an error. Async await is the modern syntax to handle promises. Using async await, the code looks like synchronous code, which makes it easier for people to read and understand the code.

What is the async/await syntax for fetch ()?

async/await syntax fits great with fetch () because it simplifies the work with promises. For example, let’s make a request to fetch some movies: fetchMovies () is an asynchronous function since it’s marked with the async keyword. await fetch ('/movies') starts an HTTP request to '/movies' URL.

How to handle async/await error in JavaScript?

I found the most profound way is async/await. async is used when we are writing any asynchronous operation and await is used when we are waiting for that asynchronous operation. There are a number of ways we can handle errors in JavaScript. In this article, we'll talk about the 3 most used ways to handle async/await error. 1. Promise.catch

How can I use async/await without using catch method?

There should be a cleaner way to use async/await without using .catch method (Well, you could if you don't mind). Using the handle utility function, we are able to avoid Unhandled promise rejection error and also handle error granularly.

Is fetchmovies Async or async?

async function fetchMovies() { const response = await fetch('/movies'); console.log(response); } fetchMovies () is an asynchronous function since it’s marked with the async keyword. await fetch ('/movies') starts an HTTP request to '/movies' URL.


Video Answer


2 Answers

Using Promise.allSettled you can run all the fetch calls in parallel and wait for them all to complete.

const test = async() => {
  const promise1  = await fetch('https://dummyimage.com/48x48/4caf50/ffffff.jpg&text=.jpg')
    .then(r => r.url)

  const promise2  = await fetch('https://dummyimage.com/bad/url/here/48x48/e91e63/ffffff.png&text=.png')
    .then(r => r.url)

  const promise3  = await fetch('https://dummyimage.com/48x48/00bcd4/ffffff.gif&text=.gif')
    .then(r => r.url)

  const results = await Promise.allSettled([promise1, promise2, promise3])

  console.log(results);

}

test();

For older support you would need to use a promise that would catch any errors from the fetch.

function makeCall () {
  return new Promise((resolve) => {
    fetch('https://dummyimage.com/48x48/4caf50/ffffff.jpg&text=.jpg')
    .then(r => console.log(r.url))
    .catch(error => resolve({ error }))
  })
}

const test = async() => {
  const promise1 = makeCall()
  const promise2 = makeCall()
  const promise3 = makeCall()

  const results = await Promise.all([promise1, promise2, promise3])

  console.log(results)

}

test()
like image 131
epascarello Avatar answered Oct 27 '22 08:10

epascarello


.error and try/catch is not what you are looking for: fetch resolves even if 404?
You need to check the value of response.ok. fetch only throws errors on network problems, not error responses.

// Background Colors
const bgHexColors   = ['f44336', 'e91e63', '9c27b0', '673ab7', '3f51b5', '2196f3', '03a9f4', '00bcd4', '009688', '4caf50', '8bc34a', 'cddc39', 'ffeb3b', 'ffc107', 'ff9800', 'ff5722', '795548', '9e9e9e', '607d8b'];
// Foreground Colors
const fgHexColors   = ['ffffff'];
// Image File Extensions
const imgExtensions = ['.png', '.gif', '.jpg'];

// First, we initialize an empty array for promises.
let myPromises = [];

// We then populate this array with 24 promises.
for(let i = 0; i < 24; i++){

  let imgWidth     = 48;
  let imgHeight    = 48;
  let bgHexColor   = bgHexColors[Math.floor(Math.random() * bgHexColors.length)];
  let fgHexColor   = fgHexColors[Math.floor(Math.random() * fgHexColors.length)];
  let imgExtension = imgExtensions[Math.floor(Math.random() * imgExtensions.length)];
  let imgText      = imgExtension;

  // We declare the promise to be added and...
  let myPromise = getRandomImage(imgWidth, imgHeight, bgHexColor, fgHexColor, imgExtension, imgText);

  // add each promise to the myPromises array.
  myPromises.push(myPromise);

}

// We create an html span element and...
let span = document.createElement('span');
span.style.color = '#ffffff';
// We set the element's span text to Please wait...
span.innerText = 'Please wait...';
// We add the span element to the document body.
document.body.append(span);


// Promise.all requires an array.
Promise.all(myPromises).then((myResponses) => {

  // debug
  // console.log(myResponses);

  // We create an html img element and...
  let span = document.createElement('span');
  span.style.color = '#ffffff';
  // We set the element's span text to Please wait...
  span.innerText = 'Done.';
  // We add the span element to the document body.
  document.body.append(span);

  // We create an html img element and...
  let br = document.createElement('br');
  // We add the br element to the document body.
  document.body.append(br);

  // for each promise resolved...
  for(let i = 0; i < myResponses.length; i++) {

    // We check its returned object containing the resolverImg...
    if(myResponses[i].resolverImg !== null) {

      // We create an html img element and...
      let img = document.createElement('img');
      // We set the element's image source to the resolverImg url returned and..
      img.src = myResponses[i].resolverImg;
      // We add the img element to the document body.
      document.body.append(img);

    }

  }

}).catch(err => console.error(err));

// The individual Promise.
// Accepts 5 arguments; image size, background color, foreground color, image file extension, image text.
async function getRandomImage(imgWidth, imgHeight, bgHexColor, fgHexColor, imgExt, imgText) {

  // The Response interface of the Fetch API represents the response to a request.
  // https://developer.mozilla.org/en-US/docs/Web/API/Response

  // We initialize the image and status as null...
  let myResolverImg      = null;
  let myResolverStatus   = null;

  // We use a Try/Catch block to check if the resolverImg exists...
  try {

    // We create a fetch async resolver...
    let myResolver       = await fetch(`https://dummyimage.com/${imgWidth}x${imgHeight}/${bgHexColor}/${fgHexColor}${imgExt}&text=${imgText}`);

    // debug
    // console.log(myResolver);

    if(myResolver.ok) {
      // if it exists, change it from null to a valid image url path.
      myResolverImg      = myResolver.url;
      myResolverStatus   = myResolver.status;
    }

    } catch (err) {
    // if fetch network error...
    console.error('Fetch network error.');
  }

  // Return js object containing image url OR, resolverImg REMAINS null as initially declared.
  return {
       resolverImg: myResolverImg,
    resolverStatus: myResolverStatus
  };

}
like image 1
user120242 Avatar answered Oct 27 '22 09:10

user120242