Angular2-与可观察的Catch闭包范围混淆 [英] Angular2- Getting confused with Observable Catch closure scope

查看:348
本文介绍了Angular2-与可观察的Catch闭包范围混淆的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

想知道你能给点帮助。当使用 catch Observable 时,我似乎有点困惑。

Wondering if you can give a little assistance. I appear to be getting myself a bit confused when it comes to using catch with Observables.

基本上我想做的是以下内容:
当我的API返回403错误,我想对我的 TokenStore ,即删除本地令牌并将用户标记为未认证。我试图这样做可能是错误的,所以请让我知道,如果有一个更好的方法来完成这个。

Basically what I'm trying to do is the following: When my API returns a 403 error, I want to perform some actions on my TokenStore, namely, delete the local token and mark the user as unauthenticated. The way I'm trying to do this may be wrong, so please do let me know if there's a better way of accomplishing this.

我试图完成这个具有以下代码:

I'm trying to accomplish this with the following code:

APIConnector.service.ts - 用于API通信方法的单一服务

APIConnector.service.ts - a single service for API communication methods

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') });
    }
}



在我使用API​​Connector的每个服务在 Observable 上有catch方法,以运行 handleError 闭包。例如

In each of my services which use the APIConnector, I have catch methods on the Observables, to run the handleError closure. 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);
}

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

However, this gives the following error:


EXCEPTION:TypeError:无法读取未定义的属性destroy

EXCEPTION: TypeError: Cannot read property 'destroy' of undefined

这是因为handleError是一个闭包。

Presumably this is because handleError is a closure. I'm unsure of the best way to deal with this, though.

任何想法都将非常感谢。

Any thoughts would be greatly appreciated

推荐答案

问题是你直接引用函数,所以你失去它的上下文。

The problem is that you reference the function directly so you lose its context. I mean it's now afunction and a method.

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

There are two ways to fix this:


  • 将函数绑定到此:

  • binding the function to this:

.catch(this._apiConnector.handleError.bind(this));

不推荐使用此方法,因为这里会丢失类型。有关详情,请参阅此链接: https://basarat.gitbooks.io/typescript/content/docs /tips/bind.html

This approach isn't recommended because you will lose types here. See this link for more details: https://basarat.gitbooks.io/typescript/content/docs/tips/bind.html

将通话换成箭头功能:

.catch((error) => {
  this._apiConnector.handleError(error);
});


这篇关于Angular2-与可观察的Catch闭包范围混淆的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆