Matias Diez Matias Diez - 1 month ago 7
TypeScript Question

How can I wait for two promises within a promise to be resolved before calling a function?

I have a forEach on a matches fetch that does this:

matches => {
matches.forEach(match => {
Promise.all([this.teamService.getTeam(match._links.homeTeam.href)])
.then( team => {
match.homeTeam = team[0].teamName;
}
);
Promise.all([this.teamService.getTeam(match._links.awayTeam.href)])
.then( team => {
match.awayTeam = team[0].teamName;
}
);
this.updateTableInformation(match);
});
return matches;
}


Explanation: I bring in an array of matches and I go through each match. Each match is a Promise that contains links to the home and away teams.

Those match.home and match.away values are also promises of teams so I wrap the teams in a Promise.all so it is resolved before assigning the value to the string type values: match.homeTeam and match.awayTeam.

The Problem:
When I call the function:

this.updateTableInformation(match);


It uses match.homeTeam and match.awayTeam but when it gets there, the team promises are not yet resolved, therefore match.homeTeam = undefined;

The Question:

How can I wait for the team promises (and the upper level match promise) to be resolved before calling updateTableInformation(match); ?

I'm using es6, es2016

Answer Source

I wrap the teams in a Promise.all so it is resolved before assigning the value to the match.

No, for that just chaining .then(…) directly to the promise would be enough.

when it gets to the function this.updateTableInformation(match), the team promises are not yet resolved

That's where you are supposed to use Promise.all, to wait for all the promises that you need to wait for and use their results in the then callback of the returned promise:

function updateMatch(match) {
    const homePromise = this.teamService.getTeam(match._links.homeTeam.href).then(team => {
        match.homeTeam = team[0].teamName;
    });
    const awayPromise = this.teamService.getTeam(match._links.awayTeam.href).then(team => {
        match.awayTeam = team[0].teamName;
    });
    return Promise.all([homePromise, awayPromise]).then(() => {
        this.updateTableInformation(match);
    });
}

Also use Promise.all to wait until all the matches in the iterated array are fulfilled. Don't use .forEach, use .map so that you get back an array of promises to use:

matches => Promise.all(matches.map(updateMatch))