问题
I want to open a loader popup when request is trying to hit and after getting response,I want to close it. Is any way with using httpclient to perform it from a single place.
回答1:
Something like this:
@Injectable()
export class I1 implements HttpInterceptor {
constructor(public service: SomeService) {
console.log(service);
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
setTimeout(() => {
this.service.loading = true;
});
return next.handle(req).do(
(event: HttpEvent<any>) => {
if (event instanceof HttpResponse) {
setTimeout(() => {
this.service.loading = false;
});
}
},
(err: any) => {
}
);
}
}
SomeService.ts:
@Injectable()
export class SomeService {
_loading = false;
constructor() {
}
set loading(isLoad: boolean) {
this._loading = isLoad;
}
get loading() {
return this._loading;
}
}
And in your Root
component inject this service:
@Component({
selector: 'my-app',
template: `
IsLoading: {{service.loading}}
<div><h3>Response</h3>{{response|async|json}}</div>
<button (click)="request()">Make request</button>`
,
})
export class AppComponent {
response: Observable<any>;
constructor(private http: HttpClient, public service: SomeService) {}
request() {
const url = 'https://jsonplaceholder.typicode.com/posts/1';
this.response = this.http.get(url, {observe: 'body'});
}
}
CODE EXAMPLE
- With using BehaviorSubject
SpinnerService:
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs/Observable';
import { share } from 'rxjs/operators';
@Injectable()
export class SpinnerService {
private visible$ = new BehaviorSubject<boolean>(false);
show() {
this.visible$.next(true);
}
hide() {
this.visible$.next(false);
}
isVisible(): Observable<boolean> {
return this.visible$.asObservable().pipe(share());
}
}
StackBlitz EXAMPLE
来源:https://stackoverflow.com/questions/49507932/httpclient-request-intercepter-like-at-time-of-getting-response-from-server