问题
Angular 6 : How to identify response of api with forkJoin
reqs = [];
if (shouldUpdatePhone) {
reqs.push(this.customerService.updatePhone(phoneUpdateRequest))
}
if (shouldUpdateAddress) {
reqs.push(this.customerService.updateAddress(addressUpdateRequest))
}
forkJoin(reqs).subscribe(result => {
console.log('result :', result);
//How to know response is from updatePhone and response from updateAddress?
});
How to can i identify response received is belong to updatePhone and updateAddress? based on identification i need to show message to user.
this both api returning Array(2) >
{model:true, code:200, message:null},
{model:true, code:200, message:null}
回答1:
You can wrap your reponses in another object that identifies their type by using the map
pipe after each request. Just like this:
reqs = [];
if (shouldUpdatePhone) {
reqs.push(this.customerService.updatePhone(phoneUpdateRequest)
.pipe(map(value => ({type: 'phone', value: value})))
.pipe(catchError(value => of({type: 'phone', failed: true}))))
}
if (shouldUpdateAddress) {
reqs.push(this.customerService.updateAddress(addressUpdateRequest)
.pipe(map(value => ({type: 'address', value: value})))
.pipe(catchError(value => of({type: 'address', failed: true}))))
}
forkJoin(reqs).subscribe(results => {
console.log('result :', results);
for(let result of results){
if(result.type == 'phone'){
if(result.failed)
console.log("Phone failed");
else
console.log("Phone: " + result.value);
}
else if(result.type == 'address'){
if(result.failed)
console.log("Address failed");
else
console.log("Address: " + result.value);
}
}
});
回答2:
You could do something like this:
forkJoin(reqs).subscribe(([phone, address]) => {
if (!shouldUpdatePhone) {
address = phone;
}
});
But I think you are overseeing something, forkJoin
emits an array of responses from all inner observables, once they are all completed. So it will only emit once, containing both responses (if they were both added to the array)
another option would be to add a pipe to the forkJoin and the inner subs (untested code):
const reqs = [];
if (shouldUpdatePhone) {
reqs.push(this.customerService.updatePhone(phoneUpdateRequest)).pipe(
map((response) => ({ phone: response }))
);
}
if (shouldUpdateAddress) {
reqs.push(this.customerService.updateAddress(addressUpdateRequest)).pipe(
map((response) => ({ address: response }))
);
}
forkJoin(reqs).pipe(
map((responses) => reponses.reduce((a, b) => ({...a, ...b}), {}))
).subscribe(result => {
// result.address;
// result.phone;
});
回答3:
Based on the RxJS documentation:
forkJoin
will wait for all passed Observables to complete and then it will emit an array with last values from corresponding Observables. So if you passn
Observables to the operator, resulting array will haven
values, where first value is the last thing emitted by the first Observable, second value is the last thing emitted by the second Observable and so on.
Therefore, your result
value should be an array with the first value being the response of the updatePhone(...)
observable and the second value is the response from the updateAddress(...)
observable.
来源:https://stackoverflow.com/questions/52009568/angular-6-how-to-identify-forkjoin-response