0

I have a nested promise that fetches data and then presents it to the DOM.

I am trying to convert it into an async/await syntax, but because it is nested with a Promise.All I am having trouble converting it.

    fetch(searchUrl)
        .then(function (response) {
          return response.json()
        })
        .then(function (data) {
          searchLoader.style.display = "none";
          for (let i = 0; i < 10; i++) {
            let stock = `${data[i].name}, (${data[i].symbol})`;
            listOfStocks.innerHTML += `<li class="list-group-item"><a href="./company.html?symbol=${data[i].symbol}">${stock}<a/></li>`;
            // console.log(data[i].symbol)
          }
          return Promise.all(data.map(item => fetch(`${BaseUrl}company/profile/${item.symbol}`)));
        })
        .then(function (response) {
          return Promise.all(response.map(x => x.json()));
        })
        .then(function (data1) {
          console.log(data1);
          for (let i = 0; i < listOfStocks.children.length; i++) {
            if (data1[i].profile.changes >= 0) {
              listOfStocks.children[i].innerHTML = `<img class="logo-for-list" src="${data1[i].profile.image}" /> ${listOfStocks.children[i].innerHTML} <span class="color-prc" style="color:green;"> ${data1[i].profile.changesPercentage}</span>`;
            } else {
              listOfStocks.children[i].innerHTML = `<img class="logo-for-list" src="${data1[i].profile.image}" /> ${listOfStocks.children[i].innerHTML} <span class="color-prc"> ${data1[i].profile.changesPercentage}</span>`;
            }
          }

Thanks

Baruch Karlin
  • 33
  • 1
  • 5
  • 1
    Just ignore the `Promise.all(…)` expression and treat it like any other promise. There's nothing to convert inside there. Can you show us your attempt at converting the linear `then` chain to `async`/`await`, please? – Bergi Feb 28 '21 at 13:28
  • I am adding as an answer- I re-tried to refactor the code and it looks o.k. – Baruch Karlin Feb 28 '21 at 13:42

3 Answers3

1

it seems to be working @bergi - thanks for the pointer

  const response = await fetch(searchUrl);
      const data = await response.json();

      searchLoader.style.display = "none";
      for (let i = 0; i < 10; i++) {
        let stock = `${data[i].name}, (${data[i].symbol})`;
        listOfStocks.innerHTML += `<li class="list-group-item"><a href="./company.html?symbol=${data[i].symbol}">${stock}<a/></li>`;
        // console.log(data[i].symbol)
      }
      const response1 = await Promise.all(data.map(item => fetch(`${BaseUrl}company/profile/${item.symbol}`)));

      const data1 = await Promise.all(response1.map(x => x.json()));

      for (let i = 0; i < listOfStocks.children.length; i++) {
        if (data1[i].profile.changes >= 0) {
          listOfStocks.children[i].innerHTML = `<img class="logo-for-list" src="${data1[i].profile.image}" /> ${listOfStocks.children[i].innerHTML} <span class="color-prc" style="color:green;"> ${data1[i].profile.changesPercentage}</span>`;
        } else {
          listOfStocks.children[i].innerHTML = `<img class="logo-for-list" src="${data1[i].profile.image}" /> ${listOfStocks.children[i].innerHTML} <span class="color-prc"> ${data1[i].profile.changesPercentage}</span>`;
        }
      }
    ```
Baruch Karlin
  • 33
  • 1
  • 5
  • Indeed :-) Don't forget [error handling on the `fetch` responses](http://blog.niftysnippets.org/2018/06/common-fetch-errors.html) though. I'd also recommend not to first fetch all responses and then to read all bodies, but do it right when each response arrives. – Bergi Feb 28 '21 at 14:00
0

This is how you would convert a Promise.then(...).then(...).then(....) chain to an async/await code :-

async function processStuff(){
  const data = await fetch(searchUrl).then((response)=>response.json());

  searchLoader.style.display = "none";

       for (let i = 0; i < 10; i++) {
            let stock = `${data[i].name}, (${data[i].symbol})`;
            listOfStocks.innerHTML += `<li class="list-group-item"><a href="./company.html?symbol=${data[i].symbol}">${stock}<a/></li>`;
            // console.log(data[i].symbol)
          }
          const response = await Promise.all(data.map(item => fetch(`${BaseUrl}company/profile/${item.symbol}`)));

          const data1 = await Promise.all(response.map(x => x.json()));

               for (let i = 0; i < listOfStocks.children.length; i++)             {
            if (data1[i].profile.changes >= 0) {
              listOfStocks.children[i].innerHTML = `<img class="logo-for-list" src="${data1[i].profile.image}" /> ${listOfStocks.children[i].innerHTML} <span class="color-prc" style="color:green;"> ${data1[i].profile.changesPercentage}</span>`;
            } else {
              listOfStocks.children[i].innerHTML = `<img class="logo-for-list" src="${data1[i].profile.image}" /> ${listOfStocks.children[i].innerHTML} <span class="color-prc"> ${data1[i].profile.changesPercentage}</span>`;
            }  
          
            }

}
processStuff();

Note - There is nothing special I did here for Promise.all() since it simply returns a Promise. Had it been just Promise.resolve(2), the approach would be the same.

Lakshya Thakur
  • 8,030
  • 1
  • 12
  • 39
0

Should be something like this:

try {
  const response = await fetch(searchURL)
  const data = await response.json()
  searchLoader.style.display = "none";
  for (let i = 0; i < 10; i++) {
    let stock = `${data[i].name}, (${data[i].symbol})`;
    listOfStocks.innerHTML += `<li class="list-group-item"><a href="./company.html?symbol=${data[i].symbol}">${stock}<a/></li>`;
    // console.log(data[i].symbol)
  }
  const data1 = await Promise.all(data.map(async (item) => {
    const response = await fetch(`${BaseUrl}company/profile/${item.symbol}`)
    return response.json()
  }));
  for (let i = 0; i < listOfStocks.children.length; i++) {
    if (data1[i].profile.changes >= 0) {
      listOfStocks.children[i].innerHTML = `<img class="logo-for-list" src="${data1[i].profile.image}" /> ${listOfStocks.children[i].innerHTML} <span class="color-prc" style="color:green;"> ${data1[i].profile.changesPercentage}</span>`;
    } else {
      listOfStocks.children[i].innerHTML = `<img class="logo-for-list" src="${data1[i].profile.image}" /> ${listOfStocks.children[i].innerHTML} <span class="color-prc"> ${data1[i].profile.changesPercentage}</span>`;
    }
  }
} catch (e) {
  console.log(e)
}
Thomas Kuhlmann
  • 943
  • 7
  • 18