2

This is how I implement Interceptor to show loading for all Http request.

 intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

       if(myCondition == true)
    {
        // my loading start showing here
        return next.handle(req).pipe(
        finalize(() => { 
                        // I hide my loading here 
                       })           );
    }
     return next.handle(req).pipe(
     finalize(() => { }));
    }

but my Http request has many data and the backend take almost 10 seconds to complete.
I just need to hide the loading only after the backend operation is finished.
But, by using the above code, the loading is hide before the backend is finished.
Do I need to handle HttpRespond like this example?

UPDATE:
I found why it is causing, I've updated my code.
I have a condition "if(myCondition == true)", I only show loading only if the condition is true. But we must have return for the intercept method, right?
So I put the "return" outside of this condition.
This return causing issue and that's why the loading disappears.
So how can I fix for a scenario like this?

6
  • Yes. You're only intercepting the outgoing request right now. The logic to hide loading should happen when the response comes back. Because you say the data takes almost 10 seconds to come back, it could be latency or whatever but if it's because it's a large data set coming back in the response, make sure you're only initially displaying a small portion of it. Rendering that much data is costly in terms of performance so your response may come back with the data and the loading icon may get hidden, but your data still may not be rendered. You can use client-side pagination to prevent that. Commented Mar 12, 2020 at 10:57
  • Can you reproduce this problem in a stackblitz? Any operators in the pipe should only be called once the response comes back. My mock demo: stackblitz.com/edit/angular-tk2bk1 Commented Mar 12, 2020 at 11:02
  • Do you have any other requests being made while you are waiting for the long-running response to come back? Commented Mar 12, 2020 at 11:18
  • @KurtHamilton , just one request Commented Mar 12, 2020 at 11:48
  • So can you recreate this in a stackblitz? Have you put nuclear levels of logging in there to try to understand what's happening? Commented Mar 12, 2020 at 11:55

2 Answers 2

3

You need to manage certain scenarios while you make an API call.

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

            this.loadingService.show(); //Initiate loader

        return next.handle(req).do((event: HttpEvent<any>) => {
            if (event instanceof HttpResponse) {
                this.loadingService.hide();
                //Closing loader when you receive reponse
            }
        }, (err: any) => {
            if (err instanceof HttpErrorResponse) {
                this.loadingService.hide();
               //Closing loader when you have Error
            }
        })
    }
Sign up to request clarification or add additional context in comments.

5 Comments

Why are you using .do? That's not in RxJS any more
I Copied a snippet from one of my projects. Modifications can be made though in code as per your requirement.
We don't really know what the problem is yet, so it would be a little premature of me to post an answer
The code OP posted should work, so there is probably something else going on here
I've faced the same issue earlier so i posted according to that. It it helps what else you need.
1

Yes you can do that there are two types of interceptors one is Request and another one is Response so on every Request interceptor we start the loading and on every Response interceptor we hide that loading.

@Injectable()
export class AppHttpInterceptor implements HttpInterceptor {
    constructor() {}
intercept(
        req: HttpRequest<any>,
        next: HttpHandler
      ): Observable<HttpEvent<any>> {
        this.loadingService.show();
        return next.handle(req).pipe(
            tap(evt => {
                if (evt instanceof HttpResponse) {
                    if(evt != null) {
                          // here we are hide the loader flag
                          this.loadingService.hide();
                     }  
                }
            }),
            catchError((err: any) => {
                if(err instanceof HttpErrorResponse) {
                    try {
                         // if we are getting the erorr we also have to hide the loader 
                         this.loadingService.hide();                      
                    } catch(e) {
                       console.log(e)
                    }
                    //log error 
                }
            }));
      }
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.