Search code examples
javascriptpromisees6-promisefetch-api

substituting other Javascript promise in chain on condition


It's been a while since I worked with JavaScript promises, so I'm getting back up to speed with the latest features.

In a browser I'm downloading a file foo.txt from the server using the Fetch API:

fetch("foo.txt").then(response => {
  if (!response.ok) {
    throw new Error(`HTTP error: ${response.status}`);
  }
  return response.arrayBuffer();
}).then(responseBuffer => {
  //TODO continue processing response
});

That works fine. But now I first want to alternately download bar.txt if foo.txt doesn't exist, and then continue the same processing chain. So I'm thinking something like this:

fetch("foo.txt").then(response => {

  if(response.status == 404) {
    //TODO try to fetch `bar.txt`
  }

How would I fetch("bar.txt") and somehow substitute its promise result in the same chain, so that I could e.g. check its response.ok and continue processing with the existing promise chain?


Solution

  • You can do just that:

    fetch("foo.txt").then(response => {
      if (response.status == 404) return fetch("bar.txt")
      else return response;
    }).then(response => {
      if (!response.ok) throw new Error(`HTTP error: ${response.status}`);
      else return response.arrayBuffer();
    }).then(responseBuffer => {
      //TODO continue processing response
    });
    

    It reads a bit easier with async/await though:

    let response = await fetch("foo.txt");
    if (response.status == 404) {
      response = await fetch("bar.txt")
    }
    if (!response.ok) throw new Error(`HTTP error: ${response.status}`);
    const responseBuffer = await response.arrayBuffer();
    //TODO continue processing response