I am using the ionic/storage package to store the api_token for users after they logged in so I can use the unique token to interact with an API.
The problem I am facing is that I need to get the value via storage.get which returns a promise and results in the headers I want to set not being set in time.
I need to return an instance of RequestOptions but can't figure out how to add the header I retrieve when it comes from a promise. Adding a header synchronous with localStorage is working fine when testing so the issue must be the asynch execution.
createAuthorizationHeader(headers: Headers) {
// this does add the header in time
localStorage.setItem('api_token', 'some token');
headers.append('Authorization', 'Bearer ' + localStorage.getItem('api_token'));
// this does not add the header in time
return this.storage.get('api_token').then((value) => {
headers.append('Authorization', 'Bearer ' + value);
});
}
getHeaders(path): RequestOptions {
let headers = new Headers({
'Accept': 'application/json',
'Content-Type': 'application/json'
});
if(!this.isGuestRoute(path)) {
this.createAuthorizationHeader(headers);
}
return new RequestOptions({ headers: headers });
}
get(path: string) {
return this._http.get(this.actionUrl + path, this.getHeaders(path))
.map(res => res.json())
.catch(this.handleError);
}
Edit: Working code now looks like this
getApiToken(): Observable<Headers> {
return Observable.fromPromise(this.storage.get('api_token'));
}
getHeaders(): Headers {
return new Headers({
'Accept': 'application/json',
'Content-Type': 'application/json'
});
}
get(path: string) {
let headers: Headers = this.getHeaders();
if(!this.isGuestRoute(path)) {
return this.getApiToken().flatMap(data => {
headers.append('Authorization', 'Bearer' + data);
return this._http.get(this.actionUrl + path, { headers : headers })
.map(res => res.json())
.catch(this.handleError);
});
}
return this._http.get(this.actionUrl + path, { headers : headers })
.map(res => res.json())
.catch(this.handleError);
}
Check out my similar problem Angular2 - Use value of Observable returning method in another Observable
If you convert the Promise to a Observable you will be able to use the rxjs flatMap function.
Let me show you what your would somewhat look like then
getApiToken(): Observable<Headers> {
return Observable.fromPromise(this.storage.get('api_token'));
//OR return Observalbe.of(this.storage.get('api_token'));
}
getHeaders(): Headers {
//create all headers here except the 'api_token'
.....
}
get(path: string): Observable<any> {
let headers: Headers = this.getHeaders();
return this.getApiToken().flatMap(data => {
headers.append('Authorization', 'Bearer'+data);
return this.http.get(this.actionUrl + path, headers)
.map(res => res.json())
.catch(this.handleError);
});
}
OR (Just learned about this so not sure if it will work)
createAuthorizationHeader(headers: Headers) {
// this does add the header in time
localStorage.setItem('api_token', 'some token');
headers.append('Authorization', 'Bearer ' + localStorage.getItem('api_token'));
// this does not add the header in time
let api_token = await this.storage.get('api_token');
headers.append('Authorization', 'Bearer ' + api_token);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With