我正在尝试将我的项目从angular 4升级到angular 5。
为此,我需要将Http的使用升级到HttpClient。
但是,我的 HttpService 是使用其他服务包装的,并且在设置 environment == "develop" 时与 MockConnectionBackend 一起使用,我无法弄清楚更改类结构以使用 HttpClient 的正确方法是什么。
export enum HttpRequestType {
Secured = 1,
Regular = 2
}
@Injectable()
//I use the HttpFactoryService in order to enable the caller to force a secure connection (call will be submitted only if user is logged in)
export class HttpFactoryService {
constructor(private readonly http: Http,
private readonly secureHttp: SecureHttpService,
private readonly oauth2: OAuth2Service) { }
public get(httpRequestType?: HttpRequestType): HttpApi {
let useSecureConnection = httpRequestType == HttpRequestType.Secured || this.oauth2.isAuthenticated();
if (useSecureConnection) {
return this.secureHttp;
}
return this.http;
}
}
//Secure http check if user is logged in. if not request is aborted.
//If user is logged in than we add the authorized header
@Injectable()
export class SecureHttpService implements HttpApi {
constructor(private readonly http: Http,
private readonly oauth2: OAuth2Service,
private readonly router: Router) {
}
get(url: string, options?: RequestOptionsArgs): Observable<Response> {
return this.request(url, extend({}, options, { method: RequestMethod.Get }));
}
post(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
return this.request(url, extend({}, options, {
body: body,
method: RequestMethod.Post
}));
}
put(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
return this.request(url, extend({}, options, {
body: body,
method: RequestMethod.Put
}));
}
delete(url: string, options?: RequestOptionsArgs): Observable<Response> {
return this.request(url, extend({}, options, { method: RequestMethod.Delete }));
}
patch(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
return this.request(url, extend({}, options, {
body: body,
method: RequestMethod.Patch
}));
}
head(url: string, options?: RequestOptionsArgs): Observable<Response> {
return this.request(url, extend({}, options, { method: RequestMethod.Head }));
}
options(url: string, options?: RequestOptionsArgs): Observable<Response> {
return this.request(url, extend({}, options, { method: RequestMethod.Options }));
}
request(request: string|Request, options?: RequestOptionsArgs): Observable<Response> {
return this.oauth2.getAccessToken()
.flatMap((accessToken: string) => {
options = options || {};
options.headers = options.headers || new Headers();
options.headers.append("Authorization", accessToken);
return this.http.request(request, options);
})
.catch((err:any) => {
if (err.status == HttpStatusCodes.Unauthorized) {
this.router.navigate(['/login']);
}
return Observable.throw(err);
})
}
}
//I created my own Http service
@NgModule({
imports: [//Cleard for simplicity]
exports: [//Cleard for simplicity],
declarations: [//Cleard for simplicity]
providers: [
HttpCacheService,
//Mocks
MockBackend,
MockBackendConnector,
{
provide:Http,
deps: [
XHRBackend,
MockBackend,
HttpCacheService,
MockBackendConnector,
],
useFactory: createHttpService
}
]
})
export function createHttpService(xhrBackend: XHRBackend,
mockBackend: MockBackend,
httpCacheService: HttpCacheService,
mockBackendConnector: MockBackendConnector) {
let xhrHttpService = new HttpService(xhrBackend, httpCacheService)
if (environment.production) {
return xhrHttpService; //On production always cancel mock
}
//We use the xhrHttpService inside mockBackendConnector in order to create a xhr call when the mock route is not presented in the mock routes
mockBackendConnector.connect(mockBackend, null, xhrHttpService);
return new HttpService(mockBackend, httpCacheService);
}
//My http service , extends the default http service calls
@Injectable()
export class HttpService extends Http implements HttpApi{
constructor(backend: ConnectionBackend,
private httpCacheService: HttpCacheService) {
super(backend, new BaseRequestOptions());
}
get(url: string, options?: RequestOptionsArgs): Observable<Response> {
return this.request(url, extend({}, options, { method: RequestMethod.Get }));
}
post(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
return this.request(url, extend({}, options, {
body: body,
method: RequestMethod.Post
}));
}
put(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
return this.request(url, extend({}, options, {
body: body,
method: RequestMethod.Put
}));
}
delete(url: string, options?: RequestOptionsArgs): Observable<Response> {
return this.request(url, extend({}, options, { method: RequestMethod.Delete }));
}
patch(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
return this.request(url, extend({}, options, {
body: body,
method: RequestMethod.Patch
}));
}
head(url: string, options?: RequestOptionsArgs): Observable<Response> {
return this.request(url, extend({}, options, { method: RequestMethod.Head }));
}
options(url: string, options?: RequestOptionsArgs): Observable<Response> {
return this.request(url, extend({}, options, { method: RequestMethod.Options }));
}
request(request: string|Request, options?: RequestOptionsArgs): Observable<Response> {
options = options || {};
let url: string;
if (typeof request === 'string') {
url = request;
request = this.isAbsoluteUrl(url) ? url: environment.serverUrl + url;
} else {
url = request.url;
request.url = this.isAbsoluteUrl(url) ? url: environment.serverUrl + url;
}
if (!options.cache) {
return this.httpRequest(request, options);
}
return this.tryFromCacheAndCacheResult(request, url, options);
}
private tryFromCacheAndCacheResult(request: string|Request, url: string, options?: RequestOptionsArgs):Observable<Response> {
}
// Customize the default behavior for all http requests here if needed
private httpRequest(request: string|Request, options: RequestOptionsArgs): Observable<Response> {
let req = super.request(request, options);
if (!options.skipErrorHandler) {
req = req.catch(this.errorHandler.bind(this));
}
return req;
}
// Customize the default error handler here if needed
private errorHandler(response: Response): Observable<Response> {
if (environment.production) {
// Avoid unchaught exceptions on production
log.error('Request error', response);
return Observable.throw(response);
}
throw response;
}
private isAbsoluteUrl(url:string): boolean {
return /^https?:\/\//i.test(url);
}
}
我觉得我做的太复杂了。我的问题是我不能对 HttpClient 使用相同的方法,并且无法理解如何按照建议使用拦截器。