Angular HTTP Interceptor-在多模块应用中显示微调器 [英] Angular HTTP Interceptor - Display spinner in multi-module app
问题描述
我正在尝试显示ng4-loading-spinner
微调器,用于对我的API进行的HTTP调用.
I'm trying to display the ng4-loading-spinner
spinner for HTTP calls made to my API.
我的代码基于以下链接中的示例:
I based my code on the examples in the following links:
- https://angular.io/guide/http#intercepting-all-requests-or-responses
- Angular4: Using HttpClient's interceptor to setup a spinner
我的Angular 5应用包含多个模块. HTTP拦截器在服务"模块中.
My Angular 5 app has multiple multiple modules. The HTTP interceptor is in the "services" module.
我认为我遇到了依赖项注入问题,因为当我使用Chrome Dev Tools调试代码时,代码HTTP拦截器代码未执行.
I think I'm having a dependency injection problem because the code HTTP interceptor code doesn't get executed when I debug my code with Chrome Dev Tools.
api-interceptor.ts
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/catch'
import { Observable } from 'rxjs/Observable';
import { Injectable } from '@angular/core';
import {
HttpEvent,
HttpInterceptor,
HttpHandler,
HttpRequest,
HttpResponse
} from '@angular/common/http';
import { Ng4LoadingSpinnerService } from 'ng4-loading-spinner';
@Injectable()
export class ApiInterceptor implements HttpInterceptor {
private count: number = 0;
constructor(private spinner: Ng4LoadingSpinnerService) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.count++;
if (this.count == 1) this.spinner.show();
let handleObs: Observable<HttpEvent<any>> = next.handle(req);
handleObs
.catch((err: any) => {
this.count--;
return Observable.throw(err);
})
.do(event => {
if (event instanceof HttpResponse) {
this.count--;
if (this.count == 0) this.spinner.hide();
}
});
return handleObs;
}
}
api.service.ts
import { Injectable, Inject } from '@angular/core';
import { Http, Response, Headers, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import { TokenService } from './token.service';
@Injectable()
export class ApiService {
constructor(
private http: Http,
private session: TokenService,
@Inject('BASE_URL') private baseUrl) { }
get(entityRoute: string): Observable<Response> {
let apiRoute = this.getApiRoute(entityRoute);
let options = this.generateRequestOptions();
return this.http.get(apiRoute, options);
}
post<T>(entityRoute: string, entity: T): Observable<Response> {
let apiRoute = this.getApiRoute(entityRoute);
let options = this.generateRequestOptions();
return this.http.post(apiRoute, entity, options);
}
put<T>(entityRoute: string, entity: T): Observable<Response> {
let apiRoute = this.getApiRoute(entityRoute);
let options = this.generateRequestOptions();
return this.http.post(apiRoute, entity, options);
}
private getApiRoute(entityRoute: string): string {
return `${this.baseUrl}api/${entityRoute}`;
}
private generateRequestOptions(): RequestOptions {
let headersObj = null;
let accessToken = this.session.getAccessToken();
if (accessToken) {
headersObj = {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + accessToken
};
} else {
headersObj = {
'Content-Type': 'application/json'
};
}
let headers = new Headers(headersObj);
return new RequestOptions({ headers: headers });
}
}
services.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpModule } from '@angular/http';
import { Ng4LoadingSpinnerModule } from 'ng4-loading-spinner';
import {
ApiInterceptor,
ApiService,
TokenService
} from './index';
@NgModule({
imports: [
CommonModule,
HttpModule,
Ng4LoadingSpinnerModule
],
providers: [
ApiInterceptor,
ApiService,
TokenService
]
})
export class ServicesModule { }
export * from './index';
app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { Ng4LoadingSpinnerModule } from 'ng4-loading-spinner';
import { BootstrapModule } from './bootstrap/bootstrap.module';
import { ServicesModule, ApiInterceptor } from './services/services.module';
import { AppComponent } from './app-component';
@NgModule({
bootstrap: [ AppComponent ],
imports: [
BrowserModule,
Ng4LoadingSpinnerModule.forRoot(),
BootstrapModule,
ServicesModule
],
providers: [
{
provide: 'BASE_URL',
useFactory: getBaseUrl
},
{
provide: HTTP_INTERCEPTORS,
useClass: ApiInterceptor,
multi: true,
}
]
})
export class AppModule {
}
export function getBaseUrl(): string {
return document.getElementsByTagName('base')[0].href;
}
推荐答案
问题是ApiService
使用的是@angular/http
中的Http
而不是@angular/common/http
中的HttpClient
.
The issue was the ApiService
was using the Http
from @angular/http
instead of HttpClient
from @angular/common/http
.
所以ApiInterceptor
没有什么可拦截的.
So the ApiInterceptor
has nothing to intercept.
这篇关于Angular HTTP Interceptor-在多模块应用中显示微调器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!