Angular2 Наблюдаемый и обещающий
Я начал использовать Angular2 Observable
, но я не могу найти что-то похожее на .then
, которое я использовал с Promises
.
Это то, что я хочу выполнить.
код от header.component.ts
public login() {
this._user = AuthService.getInstance().login(this._loginInfo);
}
код от auth.service.ts
return this._httpClient.post('LoginAction', credentials)
.map(res => res.json())
.subscribe(user => {
return new User(user);
});
Функция promises, login
возвращает Promise, которая в конечном итоге преобразуется в реальный ответ от сервера. Но с Observable это не сработает.
Есть ли способ сделать подобное? Я хочу избежать необходимости добавлять подписку внутри функции component
login
. Я хочу иметь возможность выполнять всю работу в сервисе и возвращать фактический объект в component
.
Кроме того, я попытался создать Promise
, с toPromise
, но я продолжаю получать toPromise is not a function
.
p.s. _httpClient - моя оболочка вокруг Angular2 http, в которой я готовлю запрос, добавляя некоторые заголовки и т.д.
изменить
return this._httpClient.post('LoginAction', credentials)
.map(res => res.json())
.toPromise(). <-- i keep getting that it is not a function
then(user => {
return new User(user);
});
выполнив это, мой компонент получит объект (который ему нужен), и в сервисе я мог бы делать дополнительные вещи (например, сохранять пользователя в localstorage, как только я его запустил).
И я переключился на Promise
, потому что делать то же самое с Observable
не работает (или я делаю это неправильно)?
Я вижу, что возвращаемый объект Observable (перед вызовом toPromise), но я действительно не вижу функцию toPromise
.
Ответы
Ответ 1
Когда вы вызываете subscribe(...)
, возвращается Subscription
, у которого нет toPromise()
. Если вы переместите код с subscribe
на map
, вы можете использовать toPromise()
вместо subscribe
return this._httpClient.post('LoginAction', credentials)
.map(res => res.json())
.map(user => {
return new User(user);
}).toPromise();
и вызывающий абонент получит Promise
, где он может получить значение, используя
public login() {
this._user = AuthService.getInstance().login(this._loginInfo)
.then(result => {
doSomething();
});
}
но вы получите тот же результат, если вы опустите `.toPromise(), и вызывающий использует его как
public login() {
this._user = AuthService.getInstance().login(this._loginInfo)
.subscribe(result => {
doSomething();
});
}
где единственная разница subscribe()
вместо then()
, и если пользователь библиотеки предпочитает реактивный стиль, он предпочтет использовать subscribe()
, как он привык.
Ответ 2
Вам нужно импортировать оператор Rx toPromise, например
import 'rxjs/add/operator/toPromise';
Ура!
Ответ 3
Из Angular2 документации
Мы рекомендуем добавить это в rxjs-extension.ts
```
// Observable class extensions
import 'rxjs/add/observable/of';
import 'rxjs/add/observable/throw';
// Observable operators
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/filter';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/switchMap';
```
И импортируйте его в app.module.ts
(Root Module)
import './rxjs-extensions';
Это поможет нам предотвратить дальнейшую ошибку.