My form
or component
requires 4 separate API calls to complete a "save" operation. Although only one call needs to wait for the other 3, I decided to chain all of them together for added security.
This is how I have set it up:
save() {
this.save1(saveObject1)
.subscribe(response => {
if (response === 0) {
this.processErrorResult('save1');
}
this.save2(saveObject2)
.subscribe(response2 => {
if (response2 === 0) {
this.processErrorResult('save1');
}
this.save3(saveObject3)
.subscribe(response3 => {
if (response3 === 0) {
this.processErrorResult('save1');
}
if (this.noErrorsInFirst3Saves()) {
this.save4(saveObject4)
.subscribe(response4 => {
if (response4 === 0) {
this.processErrorResult('save1');
}
if (!this.hasErrors()) {
this.router.navigate(['confirmation']);
}
});
}
});
});
});
}
private save1(saveObject: any): Observable<int> {
this.api.save1(saveObject)
.subscribe(successful => {
return Observable.of(1);
}, failed => {
return Observable.of(0);
});
}
private save2(saveObject: any): Observable<int> {
this.api.save2(saveObject)
.subscribe(successful => {
return Observable.of(1);
}, failed => {
return Observable.of(0);
});
}
private save3(saveObject: any): Observable<int> {
this.api.save3(saveObject)
.subscribe(successful => {
return Observable.of(1);
}, failed => {
return Observable.of(0);
});
}
private save4(saveObject: any): Observable<int> {
this.api.save4(saveObject)
.subscribe(successful => {
return Observable.of(1);
}, failed => {
return Observable.of(0);
});
}
I've included log messages in each save{number}
function to track their execution order and response retrieval.
Upon clicking save, the page almost immediately redirects to the confirmation page. However, I notice in Chrome Dev Tools that API responses start coming in after the redirection.
Why does this setup not properly chain the transactions? In Angular 1, using promises like .then(response => {});
made chaining easier. Is there something different about API calls causing the duplicated network requests?
The network panel in Chrome Dev Tools always shows 2 calls for every API request: an initial Options
request followed by the actual get
, post
, put
, or delete
. This behavior seems unfamiliar compared to my previous projects, possibly indicating normal API practices.
Any insights on this issue?
Edit: It's been suggested to make changes as per Harry's answer below.
I'm attempting to implement the advice but facing some confusion with the implementation. Here's a detailed view of my setup:
private save1(saveObject: any): Observable<number> {
if (saveObject.hasChanges()) {
return this.api.save1(saveObject)
.map(successful => {
return this.parseSaveResponse(successful, saveObject, true); // true indicates a successful API response
})
.catch(failed => {
return this.parseSaveResponse(successful, saveObject, false); // false indicates a failed API response
});
} else {
return Observable.of(-1); // no changes, return immediately
}
}
private parseSaveResponse(response: any, saveObject: any, transactionSuccessful: boolean) {
this.logService.logTransaction({transactionType}, saveObject, response, transactionSuccessful);
if (!transactionSuccessful) {
// add error to be displayed on the form
return 0;
}
return 1;
}
At this stage, I encounter an error at the .catch({});
line stating:
Argument of type '(error: any) => 0 | 1' is not assignable to parameter of type '(err: any, caught: Observable<0 | 1>) => ObservableInput<{}>'. Type '0 | 1' is not assignable to type 'ObservableInput<{}>'. Type '0' is not assignable to type 'ObservableInput<{}>'.)