Angular2 - Путаница с видимой областью наблюдения
Интересно, можете ли вы немного помочь. Кажется, я немного запутался, когда дело доходит до использования catch
с Observable
s.
В основном я пытаюсь сделать следующее:
Когда мой API возвращает ошибку 403, я хочу выполнить некоторые действия на моем TokenStore
, а именно, удалить локальный токен и пометить пользователя как не прошедший проверку. Способ, которым я пытаюсь это сделать, может быть неправильным, поэтому, пожалуйста, дайте мне знать, есть ли лучший способ выполнить это.
Я пытаюсь выполнить это со следующим кодом:
APIConnector.service.ts - одна служба для методов связи API
import {Injectable} from 'angular2/core';
import {Http, Response, Headers, RequestOptions} from 'angular2/http';
import {Observable} from 'rxjs/Observable';
import * as _ from 'lodash';
import {Logger} from './logger.service';
import {TokenStore} from '../stores/token.store';
@Injectable()
export class APIConnector {
private _apiUrl:string = 'https://api.sb.zerojargon.com/';
private _token:string = null;
constructor(
private _http:Http,
private _logger:Logger,
private _tokenStore:TokenStore
) {}
get(endpoint:String, includes:Array<string>) {
let includeString = (!_.isUndefined(includes)) ? this._parseIncludes(includes) : '';
let headers = this._createHeaders();
let options = new RequestOptions({ headers: headers });
return this._http.get(this._apiUrl + endpoint + '?include=' + includeString, options);
}
post(endpoint:String, formData:Object, includes:Array<string>) {
let includeString = (!_.isUndefined(includes)) ? this._parseIncludes(includes) : '';
let body = JSON.stringify(formData);
let headers = this._createHeaders();
let options = new RequestOptions({ headers: headers });
return this._http.post(this._apiUrl + endpoint + '?include=' + includeString, body, options);
}
handleError(error: Response) {
// log out the user if we get a 401 message
if (error.json().error.http_code === 401) {
this._tokenStore.destroy();
}
return Observable.throw(error.json().error || 'Server error');
}
private _parseIncludes(includes:Array<String>) {
return includes.join();
}
private _createHeaders() {
return new Headers({ 'Content-Type': 'application/json', 'Authorization': 'bearer ' + localStorage.getItem('token') });
}
}
В каждой из моих служб, которые используют APIConnector, у меня есть методы catch на Observable
s, чтобы запустить закрытие handleError
. например.
public createEvent(event:Object) {
let endpoint = this._endpoint;
return this._apiConnector.post('clients/'+this.client+'/events', event, this._defaultIncludes)
.map(res => {
return this._transformer.map('event', <Object[]>res.json());
})
.catch(this._apiConnector.handleError);
}
Однако это дает следующую ошибку:
ИСКЛЮЧЕНИЕ: TypeError: невозможно прочитать свойство "destroy" из undefined
Предположительно, это потому, что handleError является закрытием. Я не уверен в лучшем способе справиться с этим, однако.
Любые мысли будут очень признательны
Ответы
Ответ 1
Проблема в том, что вы ссылаетесь на функцию напрямую, чтобы потерять ее контекст. Я имею в виду теперь эффект и метод.
Есть два способа исправить это:
-
привязка функции к этому:
.catch(this._apiConnector.handleError.bind(this));
Этот подход не рекомендуется, потому что здесь вы потеряете типы. См. Эту ссылку для получения более подробной информации: https://basarat.gitbooks.io/typescript/content/docs/tips/bind.html
-
завершение вызова в функцию стрелки:
.catch((error) => {
this._apiConnector.handleError(error);
});