Как вернуть 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();
}
}
}