0

I have a function where I form the current sum of elements. Getcoin is the method in my Api, and it works correctly if I console.log each element during the foreach cycle. But as the result I got nothing in the return and console.log function

getCurrentCost() {
        let currentCostArr = [];
        let sum = 0;
    
        let existingEntries = JSON.parse(localStorage.getItem("walletData"));
        if (existingEntries == null) existingEntries = [];
    
        existingEntries.forEach(el => {
          this.coincapService
            .getCoin(el.id)
            .then((element) => {
              currentCostArr.push(element.priceUsd * el.amount)
            })
        });
    
        for (let i = 0; i < currentCostArr.length; i++) {
          sum += +currentCostArr[i];
        }
        console.log('cevf c ' + sum)
        console.log('current cost ' + currentCostArr)
    
        return currentCostArr;
      }

getCoin method

 getCoin = async (id) => {
    const coin = await this.getResource(`/assets/${id}`);
    return this._transformCoin(coin);
  }
2
  • 1
    You need to research about the difference between synchronous and asynchronous code in Javascript. You treat getCurrentCost as if it's synchronous, however this.coincapService.getCoin(el.id) is asynchronous, and as a results its execution gets deferred until the rest of getCurrentCost has run. The fix in this specific case will depend on how you're trying to use this function Commented Apr 3, 2022 at 0:11
  • I am trying to get the sum of the elements in my LocaleStorage via server to find out the newest price, and then, give the sum to the render() to display it Commented Apr 3, 2022 at 0:21

2 Answers 2

1

The problem is that you are not handling correctly the Promise that .getCoin() returns inside the .forEach() 'loop'. It's making multiple calls to getCoin but the code outside the forEach is not awaiting these multiple async calls, so the next lines will execute without awaiting the result of the Promises. This is causing confusion in execution order logic of your code, behaving different than what you are expecting. Actually the function getCurrentCost() is ending before the Promises inside the loop resolves.

One way to solve your problem is replacing the .forEach() with .map(), which will return several Promises that will be awaited will Promise.all(), behaving the way it's expected.

//don't forget to turn the function async, so you can use await keyword.
async getCurrentCost() {

  let sum = 0;  
  let existingEntries = JSON.parse(localStorage.getItem("walletData"));
  if (existingEntries == null) existingEntries = [];
    
  await Promise.all(existingEntries.map(async (el) => {
    const coin = await this.coincapService.getCoin(el.id)
    currentCostArr.push(coin.priceUsd * coin.amount)
  })
  
  return currentCostArr
}
Sign up to request clarification or add additional context in comments.

2 Comments

but is there a way to assign currentCostArr to the external variable to use in another function? Because as a result I get promise{pendig}
@roninbony, async functions always return Promises, that resolve with the returned value of the async function itself. To use this value you need to chain a then() method or - with a more modern syntax - you need to await the async function. In this case getCurrentConst().then(result => {console.log(result)}). The result argument - that is automatically passed to then() - is the resolved value of the async function which then() is chained to (in this case result is the currentCostArr array), so inside the then() block you can assign result to an external variable.
0

Your forEach loop pushes values in you array asynchronously.

You calculate the sum before you get your array filled up with values.

2 Comments

but how shall I do in that case? I understand that I should put await somewhere? but clearly a dont understand where
I don't think the forEach method is the one to go with. You need to create a loop of promises. Take a look at this link: stackoverflow.com/questions/40328932/…

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.