Nested order of a Promise structure
I'm trying to achieve something a little tricky since I'm not used to Promise yet.
I want to fill out a card <Id, ObjectInfo>
I have two API points:
- gets all users
- the other gets the ObjectInfo given by the Id
This is what I have:
const result: Map<string, String[]> = new Map();
return this.http.get(this.adress + '/', this.options).toPromise()
.then((response) => {
for (const id of response.json()){
this.http.get(this.adress + '/' + id + '/properties').toPromise()
.then((rep) => {
result.set(id, rep.json());
console.log('#1: ', result);
}).catch(this.handleError)
}
})
.then(() => console.log('#2: ', result))
.then(() => result)
.catch(this.handleError);
So, here I would like # 1 to be followed by # 2 in the console, but it is not. I know what I should try with Promise.all()
, but I really don't know how to set it up, since I create my Promises in a nested loop.
This is for an Angular project, the actual code works so far, but throws ExpressionChangedAfterItHasBeenCheckedError.
To avoid this, changing my promise function should do the trick.
source to share
This piece of code
.then((response) => {
// <-- HERE -->
// this function must return a promise
for (const id of response.json()){
// ...
}
})
.then(() => {
// right now, this function executes **before** the requests
// in the promise above are resolved
});
Should return a promise allowing all individual promises within it (those built in a loop), so the chain of promises can be in the desired order - wait for all promises in the loop before continuing.
Usage Promise.all
here is natural match, just replace for..of
with array display:
.then((response) => {
return Promise.all(
Array
.from(response.json())
.map(id => {
return this.http.get(this.adress + '/' + id + '/properties')
.toPromise()
.then((rep) => {
result.set(id, rep.json());
console.log('#1: ', result);
})
.catch(this.handleError)
})
);
})
.then(...)
source to share