I am kind of new to Angular 4 and Observables
and everything related to it.
I am trying to execute two http
requests one after another (only when the first one succeeds).
I'm using this code:
public getCompany(id: string): any {
let company = null;
this.authService.isValidUser().subscribe(response => {
const token = this.tokenStorageService.getTokenFromStorage();
const requestUrl = environment.gatewayUrl + environment.companyService + environment.getCompanyEndPoint + id;
const headers = new Headers();
headers.set('Authorization', 'Bearer ' + token);
const options = new RequestOptions({headers: headers});
return this.http.get(requestUrl, options).catch(this.errorService.handleError);
}, (error: AppError) => {
// ........ //
});
}
This is the isValidUser()
method code:
public isValidUser(): any {
const token = this.tokeStorageService.getTokenFromStorage();
if (!token) {
console.log('cannot find token');
return false;
}
const requestUrl = environment.gatewayUrl + environment.authorizationService + environment.userServiceEndPoint;
const headers = new Headers();
headers.set('Authorization', 'Bearer ' + token);
const options = new RequestOptions({headers: headers});
return this.http.get(requestUrl, options).catch(this.errorService.handleError);
}
The idea here is to only return return this.http.get(requestUrl, options).catch(this.errorService.handleError);
after the authService.isValidUser()
code worked.
I don't think this is a proper way of performing such requests, since my second request is already completed before the first one does.
Maybe I am missing some way on how to do it properly?
Thank you.
Where is code where you try to chain these two functions?
You can achieve what you want using
switchMap
operator. Here is docs for it.I think you need something like this:
Don't forget to add
import 'rxjs/add/operator/switchMap';
. You can also usemergeMap
orflatMap
(mergeMap
is synonim forflatMap
), but it is not preferred.As @BeetleJuice mentioned in comments: Why
switchMap
is better? For example, you use mergeMap or flatMap and something caused another call of that code. Even if two first requests was not finished new ones will be sended. It is even possible that second bundle of requests will be finished faster than first one. After that first bundle finishes and you have wrong data in your state. To solve this RxJS provides perfect operatorswitchMap
. If you used this operator in situation above then first observable (first request bundle) will be cancelled. Only last observable (from last call) will stay alive. You need switchMap only if you have possibility to run that code several times in a short period of time. If you know that this code will run only oncemergeMap
/flatMap
will do same for you.Also, check out this post.
Update 3/28/2020: With new versions of rxjs, you can no longer call the switchMap operator on the returned Observable. Instead, you need to call pipe on the observable and pass in what should happen afterwards. For example:
Multiple operators can be passed into the pipe function as well. More info can be found on the rxjs site on the operators page