问题
I have a loading-interceptor who shows up a loading every time I make a http request and it works very well,the loading spinner its full screen, but I made a searchcomponent, that it is an input and every time I write inside the input, it make a http request and get all the data, but the problem is that the loading shows up in full screen and I want that loading have another behaivor in this kind of request, how can I say to my interceptor that when the call is made by the input dont shows up the loading?
//this is the code of my interceptor
@Injectable({
providedIn: 'root'
})
export class LoadinInterceptorService implements HttpInterceptor {
constructor(private spinner:NgxSpinnerService, private router: Router) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.router;
this.spinner.show();
return next.handle(req).pipe(
finalize(() => this.spinner.hide())
);
}
}
回答1:
As far as I know, the HttpInterceptor
can't really tell where the request originates from.
Given that, if your NgxSpinnerService
is a singleton, then you could make it stateful and set a flag before the input
makes its HTTP request. This flag would tell the NgxSpinnerService to display the spinner differently. You will also want to unset that flag after the input's HTTP request is complete. You could wrap that logic in your own custom-made HttpClient
-like service.
You could also set something special in the request (ie: in the header, on the query string) and detect that instead. Note that unless you modify the request, that flag will be sent to the server for no reason.
Note that there is something to keep in mind with this approach and your current interceptor:
If you send two HTTP request, they will both set the flag and call your spinner.show
. Then, when the first request completes, it will unset the flag and call spinner.hide
. This means that even though the second request is still in-flight, your spinner will be gone...
This can be fixed by having a counter of how many times show()
has been called. You decrease it when calling hide()
, and if this counter is now 0, only then you actually hide the spinner. If its not 0, another request is in-flight so don't hide the spinner.
You can see an example here: https://stackoverflow.com/a/51813213/78804
回答2:
Here is how i handled the same :
a) Add 'hideSpinnerIcon' property in request header for this particular request
@Injectable()
export class AuthHttpInterceptor implements HttpInterceptor {
constructor(
private activateRoute: ActivatedRoute,
private loaderSvc: LoaderService
) {}
// "Counter" keeps track to stop spinner for corresponding request only
counter = 0;
intercept(req: HttpRequest<any>, next: HttpHandler) {
// Start Spinner only if it does not have 'hideSpinnerIcon' header
if (!_.get(req.headers, 'hideSpinnerIcon')) {
this.counter++;
if (this.counter === 1) {
this._loaderSvc.start();
}
}
next.handle(req).pipe(
tap((event: HttpEvent<any>) => updateSpinner(req); ),
catchError((error: HttpErrorResponse) => {
updateSpinner(req,true);
return throwError(error);
});
);
}
// Reduce Counter here if got success response from api or Errored Out
// don't alter when hideSpinnerIcon is set
private updateSpinner(req,isErroredOut?) {
if (!_.get(req.headers, 'hideSpinnerIcon')) {
this.counter--;
}
if (isErroredOut || this.counter === 0) {
this._loaderSvc.stop();
}
}
}
With above code :
a) You can align spinner's start/stop to the corresponding request.
b) If any api is errored out, we can stop the spinner and show appropriate error message, instead of the infinite spins.
c) For any api having metadata as 'hideSpinnerIcon' in headers, it will not show spinner
NOTE Write a http-wrapper-service to include these activities for better maintainability and seggregation
来源:https://stackoverflow.com/questions/56499192/how-tell-interceptor-dont-show-up-the-spinner