I have a "Token" service that returns an access-token. Then I have many other services that use this service to get an access-token before they can make an API call to the backend with the token included in the request header.
The problem is that many of these services are calling the Token service almost simultaneously, so before the first call to the token service has returned and has been "cached" the next call is fired...
Resulting into multiple calls to the backend and getting multiple tokens.
Can somebody please tell me how to stop the multiple calls to the backend. Or how to run the Token service before everything else and cache the result and only then allow the application/services to run/bootstrap.
I'am using angular 2.4.4
Any help/suggestion is appreciated
import {Injectable} from '@angular/core';
import {Http} from '@angular/http';
import 'rxjs/add/operator/toPromise';
export class Token{
private cachedTokenObject = {
'tokenKey':false,
'userName':"johndoe@gmail.com",
'password':"1234",
'applicationId':"12344"
};
constructor(private _http: Http){}
getAccessToken():Promise<Object>{
if( this.cachedTokenObject.tokenKey ){
console.log("returning chached token");
return Promise.resolve( this.cachedTokenObject );
}else{
console.log("getting new token...");
const tokenHeaders = "username=" + this.cachedTokenObject.userName + "&password=" + this.cachedTokenObject.password +"&grant_type=password";
return this._http.post("https://someurl.com", tokenHeaders)
.toPromise()
.then( result => {
if( result.json().hasOwnProperty('access_token') ){
this.cachedTokenObject.tokenKey = result.json()['access_token'];
return this.cachedTokenObject;
}else{
console.log('"access_token" property not found in access object');
return {};
}
} )
.catch(error =>{
console.error('*** getAccessToken error ***', error);
Promise.reject(error);
});
}
}
}
import {Injectable} from '@angular/core';
import {Http} from '@angular/http';
import 'rxjs/add/operator/toPromise';
import { Headers, RequestOptions } from '@angular/http';
import {AccessTokenService} from './access-token.service';
@Injectable()
export class LanguageService{
private cachedLanguages:any;
constructor(private _http: Http, private _accessTokenService:AccessTokenService){}
getLanguages(){
return this._accessTokenService.getAccessToken().then( token => {
if(this.cachedLanguages){
console.log('returning cached languages', this.cachedLanguages);
return Promise.resolve(this.cachedLanguages);
}else{
let headers = new Headers({ 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + token['tokenKey']});
let options = new RequestOptions({ headers: headers });
return this._http.get('https://someUrl/languages', options)
.toPromise()
.then(resp => {
this.cachedLanguages = JSON.parse( resp.json() );
return this.cachedLanguages;
})
.catch(error =>{
console.error('*** LanguageService error ***', error);
Promise.reject(error);
});
}
});
}
}