Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular2中的自定义Http服务。循环依赖错误_Angular_Angular2 Services - Fatal编程技术网

Angular2中的自定义Http服务。循环依赖错误

Angular2中的自定义Http服务。循环依赖错误,angular,angular2-services,Angular,Angular2 Services,我已经创建了自定义Http服务来覆盖“request”方法,该方法在需要时更新每个请求上的令牌。但问题是我收到了“循环依赖”错误。知道怎么修理吗 自定义Http服务: import { Injectable } from '@angular/core'; import { Request, XHRBackend, RequestOptions, Response, Http, RequestOptionsArgs, Headers } from '@angular/http'; impo

我已经创建了自定义Http服务来覆盖“request”方法,该方法在需要时更新每个请求上的令牌。但问题是我收到了“循环依赖”错误。知道怎么修理吗

自定义Http服务:

import { Injectable } from '@angular/core';
import {
    Request, XHRBackend, RequestOptions, Response, Http, RequestOptionsArgs, Headers } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
import {UserService} from "../services/user.service";

@Injectable()
export class VodHttpService extends Http {

    constructor(backend: XHRBackend, defaultOptions: RequestOptions, private userService : UserService ) {

        super(backend, defaultOptions);
    }

    request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {

        //adding access token to each http request before calling super(..,..)
        let token = this.userService.token;
        if (typeof url === 'string') {
            if (!options) {
                options = { headers: new Headers() };
            }

            if ( url != this.userService.PUBLIC_TOKEN_URL ) {
                options.headers.set('Authorization', `Bearer ${token}`);
            }
        }
        else {

            if ( url.url != this.userService.PUBLIC_TOKEN_URL ) {
                url.headers.set('Authorization', `Bearer ${token}`);
            }
        }

        console.log(url);

        return super.request(url, options)
            .catch((error) => {
                //if got authorization error - try to update access token
                if (error.status = 401) {
                    return this.userService.updateToken()
                        .flatMap((result: boolean) => {
                            //if got new access token - retry request
                            if (result) {
                                return this.request(url, options);
                            }
                            //otherwise - throw error
                            else {
                                return Observable.throw(new Error('Can\'t refresh the token'));
                            }

                        })
                }
                else {
                    Observable.throw(error);
                }
            })

    }

}
从'@angular/core'导入{Injectable};
进口{
来自“@angular/Http”的Request、XHRBackend、RequestOptions、Response、Http、RequestOptionsArgs、Headers};
从“rxjs/Observable”导入{Observable};
导入“rxjs/add/operator/catch”;
导入“rxjs/add/observable/throw”;
从“./services/user.service”导入{UserService};
@可注射()
导出类VodHttpService扩展了Http{
构造函数(后端:XHRBackend,defaultOptions:RequestOptions,私有userService:userService){
超级(后端,默认选项);
}
请求(url:string |请求,选项?:RequestOptionsArgs):可观察{
//在调用super(..)之前向每个http请求添加访问令牌
让token=this.userService.token;
如果(url的类型=='string'){
如果(!选项){
选项={headers:newheaders()};
}
如果(url!=this.userService.PUBLIC\u令牌\u url){
options.headers.set('Authorization','Bearer${token}`);
}
}
否则{
if(url.url!=this.userService.PUBLIC\u TOKEN\u url){
set('Authorization','Bearer${token}`);
}
}
console.log(url);
返回super.request(url、选项)
.catch((错误)=>{
//如果获得授权错误-尝试更新访问令牌
如果(error.status=401){
返回这个.userService.updateToken()
.flatMap((结果:布尔)=>{
//如果获得新的访问令牌-重试请求
如果(结果){
返回此.request(url、选项);
}
//否则-抛出错误
否则{
return Observable.throw(新错误('Can't refresh the token'));
}
})
}
否则{
可观察的投掷(错误);
}
})
}
}
我的singleton用户服务看起来像:

import {Component, Injectable, Injector} from '@angular/core';
import {Http} from "@angular/http";
import {Observable} from "rxjs";
import {environment} from "../../environments/environment";

@Injectable()
export class UserService {

    public token : string;
    public PUBLIC_TOKEN_URL = environment.token_url;

    constructor (private _http: Http) { }

    updateToken() : Observable<boolean> {

        let url = this.PUBLIC_TOKEN_URL;

        return this._http.get(url).map( res => {

            // return res.json();
            if (typeof res.json().access_token !== 'undefined'){

                this.token = res.json().access_token;
                return true;
            } else {

                return false;
            }
        });
    }

}
从“@angular/core”导入{Component,Injectable,Injector};
从“@angular/Http”导入{Http};
从“rxjs”导入{observeable};
从“../../environments/environment”导入{environment}”;
@可注射()
导出类用户服务{
公共令牌:字符串;
public-public\u-TOKEN\u-URL=environment.TOKEN\u-URL;
构造函数(私有http:http){}
updateToken():可观察{
让url=this.PUBLIC\u TOKEN\u url;
返回此。_http.get(url.map)(res=>{
//返回res.json();
if(typeof res.json().access_token!=“未定义”){
this.token=res.json().access_token;
返回true;
}否则{
返回false;
}
});
}
}

我知道使用Injector解决问题的方法在哪里,但我认为这是一种丑陋的方法。

自定义VodHttpService的提供商定义不正确。应该是这样的:

export function vodHttpFactory(backend: XHRBackend, options: RequestOptions, userService: UserService) {
      return new VodHttpService(backend, options, userService);
    }

@NgModule({
// other stuff 
providers: [ 
    UserService,
    {
      provide: VodHttpService,
      useFactory: vodHttpFactory,
      deps: [XHRBackend, RequestOptions, UserService]
    }
  ]
})

请注意,
vodHttpFactory
函数是这样编写的,以便在需要时与AOT兼容。

您将
UserService
注入到一个http服务中,这在我看来是不正确的。正确的方法是抛弃http,使用新的HttpClient替换它,并编写一个拦截器。您是否也可以在向提供商注册这两个服务的地方发布代码?(我假设是在模块定义中)@AndreiMatracaru,它看起来是这样的:`providers:[UserService,{provide:Http,useClass:VodHttpService}`