想知道你是否可以提供一些帮助。在将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的每个服务中,我都在Observable
上捕获方法,以运行handleError
闭包。 e.g。
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);
}
但是,这会出现以下错误:
EXCEPTION:TypeError:无法读取未定义的属性'destroy'
大概这是因为handleError是一个闭包。不过,我不确定解决这个问题的最佳方法。
任何想法都将不胜感激
答案 0 :(得分:23)
问题是您直接引用该函数,因此会丢失其上下文。我的意思是它现在是一个功能和方法。
有两种方法可以解决这个问题:
将函数绑定到此:
.catch(this._apiConnector.handleError.bind(this));
不推荐使用此方法,因为此处会丢失类型。有关详细信息,请参阅此链接:https://basarat.gitbooks.io/typescript/content/docs/tips/bind.html
将调用包装成箭头函数:
.catch((error) => {
this._apiConnector.handleError(error);
});