Reputation: 124
I have a service named API and the first thing the service has to do is checking if the API token is valid, when the token is valid continue executing the called function. The issue here is that requesting a new token and the API call are being called at the same time.
I have tried changing the checkToken function to await and changing the final API call to async, that does not work because the function is an Observable.
Function checkToken
/*
This function has to run FIRST before the api call (below) is beigin executed.
The issue now is both functions are running at the same time, when the token is expired the call will fail.
*/
checkToken(): Observable<any> {
//this function will check the API token and either request a new token or do nothing.
// Check if session is valid based on timestamp
if (Number(currentTimestamp) + 5000 >= Number(userSession)) {
// Session is valid, do nothing.
return;
} else {
// Get new token and save in storage
return;
}
}
Example of a API call (i have multiple types of calls in my service)
getValuations(): Observable<Valuation[]> {
this.checkToken(); // This function has to run (and complete) first before continue.
//The issue now is that the function below is executing at the same time as
checkToken()
return this.http.get<Valuation[]>();
}
Here i'm consuming the data.
this.apiService.getValuations(this.Taxid).subscribe(res => {
});
I expect the checkToken function to run first and continue with the getValuations function. But obviously they are executing at the same time, what will result in executing the API call with a invalid token.
Upvotes: 1
Views: 345
Reputation: 5602
You should update your code like this:
checkToken(): Observable<any> {
//this function will check the API token and either request a new token or do nothing.
// Check if session is valid based on timestamp
if (Number(currentTimestamp) + 5000 >= Number(userSession)) {
// Session is valid, do nothing.
//and let the observable pipe line handle it
return of(true);
} else {
// Get new token and save in storage
//session is not valid then first get the token and save ithe new token in the storage
//adjust this code to have API which gets the new token
return this.apiMethodWhichGetsTheNewToken()
.pipe(
map(newToken => {
//save the token in the storage....
return true;
})
)
}
}
And now use checkToken() method which returns an observable like this:
getValuations(): Observable<Valuation[]> {
return this.checkToken()
.pipe(switchMap(token => this.http.get<Valuation[]>()));
}
Upvotes: 0
Reputation: 807
You simply need to pipe the response of new token creation or checking. Something on these lines.
//this is returning an observable, simply pipe its response.
checkToken(): Observable<any> {
//this function will check the API token and either request a new token or do nothing.
}
getValuations(): Observable<Valuation[]> {
//this is going to call checkToken() first, when that is complete
// this.http.get() request will be called.
return this.checkToken().pipe(
mergeMap(_ => this.http.get<Valuation[]>())
);
}
Upvotes: 0
Reputation:
Use the switchMap
operator :
getValuations(): Observable<Valuation[]> {
return this.checkToken()
.pipe(switchMap(token => this.http.get<Valuation[]>()));
}
This will
Upvotes: 2