I am trying to return an observable after a successful completion of my Promise, but that function is not returning Observable. To be specific to code, i want to fetch auth
You would be returning a Promise
(if you hadn't missed the return
part in front of it) which would return an Observable
on success. Consider using Observables
only, rather than mixing them both.
You can also encapsulate it into a new Observable
: new Observable(observer =>
https://angular-2-training-book.rangle.io/handout/observables/using_observables.html
Use fromPromise to convert the promise into an observable and use mergeMap to emit the HTTP response into the composed observable:
import { Observable } from 'rxjs/Observable/';
import 'rxjs/add/observable/fromPromise';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/mergeMap';
logout(): Observable<any>{
return Observable.fromPromise(this.userData.getAuthToken()).mergeMap(token => {
this.token = token;
this.headers = new Headers({
"X-USER-TOKEN": token
});
this.options = new RequestOptions({
headers: this.headers
});
var logout_url = "Api logout method";
return this.http.post(logout_url, {}, this.options).map(res => res.json());
});
}
Answer from Sunil worked for my use case, this is my working example. I am using this in my http interceptor to append acces token to the HTTP request
import {from, Observable} from "rxjs";
import {mergeMap} from "rxjs/operators";
handleTokenExpiration(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (this.isAccessTokenPresent()) {
request = request.clone({
setHeaders: {
Authorization: `Bearer ${this.getAccessToken()}`
}
});
return next.handle(request);
} else {
if (this.isRefreshTokenPresent()) {
return from(this.refreshToken(this.getRefreshToken())).pipe(mergeMap(res => {
request = request.clone({
setHeaders: {
Authorization: `Bearer ${this.getAccessToken()}`
}
});
return next.handle(request);
}));
} else {
this.logout();
}
}
}
With RXJS>6, fromPromise
is merged into from
function and to use mergeMap
, you need to use pipe
first. So this code will work
import { Observable, from } from "rxjs";
import { map, mergeMap } from "rxjs/operators";
logout(): Observable<any>{
return from(this.userData.getAuthToken()).pipe(mergeMap(token => {
this.token = token;
this.headers = new Headers({
"X-USER-TOKEN": token
});
this.options = new RequestOptions({
headers: this.headers
});
var logout_url = "Api logout method";
return this.http.post(logout_url, {}, this.options).map(res => res.json());
}));
}