How to return Observable after some promise will be resolved in Ionic 2 / Angular 2?

I try to return the observable after the successful completion of my promise, but this function does not return Observable. To be specific to the code, I want to extract the authentication token from the repository (returns a promise), and after this data is received, generate a Post request for Api (returns Observable). Thus, the exalted text gives an error in the function that "a function whose declared type is neither" void "nor" any "should return the value" below my code,

logout() : Observable<any>{ this.userData.getAuthToken().then((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()) }); } 

if I just execute the mail request then it returns exactly like that

 return this.http.post(logout_url,{},this.options) .map (res => res.json()) 

but when I try to get the data, it does not return a value from this mail request. Any help would be much appreciated! thanks in advance

+16
source share
4 answers

Use fromPromise to convert the promise to observable and use mergeMap to fix the HTTP response in the folded 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()); }); } 
+40
source

For RXJS> 6, fromPromise combines with the from function, and to use mergeMap you must first use pipe . 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()); })); } 
+5
source

You will return Promise (if you did not miss the return part before it), which would return the success of the Observable . Consider using Observables rather than mixing them.

You can also encapsulate it in a new Observable : new Observable(observer =>
https://angular-2-training-book.rangle.io/handout/observables/using_observables.html

+2
source

The answer from Sunil worked for my use case, this is my working example. I use this in my http interceptor to add an access token to an 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(); } } } 
0
source

Source: https://habr.com/ru/post/1262628/


All Articles