Vincent
Vincent

Reputation: 1304

Modify array object by async method under async forEach loop

First of all, I have an array of users that contains some basic data, such as

{"id": "1", "name": "a" }, {"id": "2", "name": "b" }

Now by calling a remote API: self.getDrinks for each user.id, it returns a new array drinks[]. Then I want to integrate the drinks into each user, finally it should be:

{"id": "1", "name": "a", "drinks": [{"id": "1-1", "name": "coke"}, {"id": "1-2", "name": "orange"}]}, {"id": "2", "name": "b", "drinks": [{"id": "2-1", "name": "coke"}, {"id": "2-2", "name": "lime"}] }

I used noSQL so that I have to do async functions to resolve return data:

Result {
  result (object, optional),
  message (string, optional),
  error (integer, optional)
}

So here is my function:

var self = this;
var itemsProcessed = 0;

this.users.forEach(function (user, idx, arr) {

  //assume the API getDrinks needs more parameters like below

  self.getDrinks(user.id, "getDrink", 0, 100, '', '', '', '', '') 
    .then((data: Result) => {
      itemsProcessed++;
      arr[idx].drinks = data.result.drinks;            
      }
      if (itemsProcessed === arr.length) {
        Logger.debug("Expected Result: " + JSON.stringify(arr));
      }
    })
    .catch(reason => Logger.error(reason));
});

Logger.debug("UnExpected Result: " + JSON.stringify(this.users));

As you can see, finally I cannot get correct this.users since it is modified in then function under forEach.

Some people suggest me to use Promise.all() but it always reports syntax error due to the return type is an array drinks[]

Upvotes: 2

Views: 2858

Answers (1)

Jaromanda X
Jaromanda X

Reputation: 1

Using promise.all you should be able to simplify your code to the following:

Promise.all(this.users.map((user, idx, arr) => 
    this.getDrinks(user.id, "getDrink", 0, 100, '', '', '', '', '') 
    .then((data: Result) => {
        itemsProcessed++;
        user.drinks = data.result.drinks;            
    })
    .catch(reason => Logger.error(reason))
))
.then(() => Logger.debug("UnExpected Result: " + JSON.stringify(this.users)));

Upvotes: 1

Related Questions