I am working with Angular/rxjs 6. I am having a hard time trying to get an observable sequence to run correctly. Here is the pseudo code for what I am trying to accomplish.
Receive a request to change systems:
- Check permissions
- Get API1 URL from another observable
- Call API1 to request a system change
- If there was a problem quit to let user know
- Call API2 to request a system change
- If there was a problem quit to let user know
- Save results
- Navigate to new system
I am not sure if my current approach is correct. It does not seem elegant because there is a lot going on and it is hard to follow. Some of this works but the response from the last http call does not return to the .toPromise().then()
.
Component:
changeSystem(systemID: string) {
if(! this._service.changeSystem(systemID))
this.toastError("A problem occurred");
}
Service:
public changeSystem(systemID: string): boolean {
if (!systemID) {
this.log("System ID is missing");
return false;
}
if(this.currentSystemID === systemID) {
return true;
} else {
this.setNewSystem(systemID).toPromise()
.then(success => { // <-- the code here never runs
if (success)
this.router.navigate(['/dashboard/', systemID])
else
return false;
}
}
}
private setNewSystem(systemID: string): Observable<boolean> {
if (!this.isAuthorized(systemID)) {
this.log('system is not authorized for user');
return Observable.of(false);
}
return this.setAlphaSystem(systemID).pipe(
concatMap(alphaResult => {
if (!alphaResult) {
this.log('failed to set alpha system');
return Observable.of(false);
} else {
return this.setBetaSystem(systemID);
}
}));
}
private setAlphaSystem(systemID: string): Observable<boolean> {
return this.alphaSystemRootUrl$.pipe(
concatMap(alphaUrl => {
const url = alphaUrl + 'pages/' + systemID + '/Home/ChangeSystem/';
return this.http.get(url, { headers: { 'Anonymous': 'true' }, withCredentials: true })
.map(data => {
let response = JSON.parse(JSON.stringify(data));
if (response.error) {
return false;
} else {
return true;
}
}).catch(err => {
this.log('Failed change system request on alpha: ' + JSON.stringify(err));
return Observable.of(false);
});
}));
}
private setBetaSystem(systemID: string): Observable<boolean> {
return this.changeBetaSystem(systemID).map(systemData => {
this.saveSystemData(systemData);
return true;
}).catch((err: ErrorInfo) => {
this.log('Failed change system request on beta: ' + err.message);
return Observable.of(false);
});
}
private changeBetaSystem(systemID: string): Observable<SystemData> {
const json = JSON.stringify(systemID);
return this.http.post<SystemData>("api/System/ChangeSystem", json, this.httpOptions)
.pipe(catchError(new ErrorInfo().parseObservableResponseError));
}
Do I need a switchmap in setBetaSystem instead of map?
I saw some examples where the component subscribed to a behavior subject that the service functions updated as the processing continued. Should I try that?
Any help is much appreciated!