Как вернуть Observable после того, как некоторое обещание будет разрешено в Ionic 2/Angular 2?

Я пытаюсь вернуть наблюдаемое после успешного завершения моего обещания, но эта функция не возвращается Observable. Чтобы быть конкретным для кода, я хочу извлечь токен аутентификации из хранилища (возвращает обещание), и после того, как эти данные будут получены, сгенерируйте запрос Post для Api (возвращает Observable). Таким образом, возвышенный текст дает ошибку в функции, что "функция, объявленный тип которой не является ни" void ", ни" any ", должна возвращать значение" ниже мой код,

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())
  });
}

если я просто выполняю почтовый запрос, тогда он возвращает точно такой

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

но когда я пытаюсь получить данные, он не возвращает значение из этого почтового запроса. Любая помощь будет высоко ценится! Спасибо заранее

Ответ 1

Используйте fromPromise, чтобы преобразовать обещание в наблюдаемое и использовать mergeMap, чтобы исправить HTTP-ответ в сложенном наблюдаемом:

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());
  });
}

Ответ 2

При RXJS> 6 fromPromise объединяется с функцией from, и для использования mergeMap сначала необходимо использовать pipe. Так что этот код будет работать

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());
  }));
}

Ответ 3

Вы вернете Promise (если вы не пропустили перед ним часть return), которая вернула бы успех Observable. Рассмотрите возможность использования Observables, а не для их смешивания.

Вы также можете инкапсулировать его в новый Observable: new Observable(observer =>
https://angular-2-training-book.rangle.io/handout/observables/using_observables.html

Ответ 4

Ответ от Sunil работал для моего варианта использования, это мой рабочий пример. Я использую это в своем перехватчике http, чтобы добавить токен доступа к HTTP-запросу

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();
      }
    }
  }