Angular2-与Observable Catch闭包范围混淆

use*_*138 15 closures scope angular

想知道你是否可以提供一些帮助.我似乎得到自己当涉及到使用有点困惑catchObservable秒.

基本上我要做的是以下内容:当我的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') });
    }
}
Run Code Online (Sandbox Code Playgroud)

在我使用API​​Connector的每个服务中,我都在Observables 上捕获方法,以运行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);
}
Run Code Online (Sandbox Code Playgroud)

但是,这会产生以下错误:

EXCEPTION:TypeError:无法读取undefined的属性'destroy'

大概这是因为handleError是一个闭包.不过,我不确定解决这个问题的最佳方法.

任何想法将不胜感激

Thi*_*ier 23

问题是您直接引用该函数,因此会丢失其上下文.我的意思是它现在是一个功能和方法.

有两种方法可以解决这个问题:

  • 这个答案是正确的,有一个小的调整.catch方法要求你返回一些东西,所以括号内需要`return`. (4认同)
  • 如果要抛出新的或相同的错误,则返回一些内容:"return Observable.throw(error);".如果不是你的情况,不要回来.该错误不会传播到另一个catch或第二个subscribe回调. (2认同)
  • 我有同样的问题,这个答案解决了它.但是我喜欢没有括号的解决方案,没有'_apiConnector'方式更好`.catch(error => this.handleError(error));` (2认同)