Chau Tran
Chau Tran

Reputation: 5088

Angular 5 HttpInterceptor Flow

I am trying to implement HttpInterceptor in one of my Angular application to show a spinner on every request. The spinner shows beautifully. However, I also implemented a notificationService which utilizes SweetAlert to display notification modals based on the response from the server. I was able to display a Success modal but not Error modal. My codes are below:

INTERCEPTOR:

 intercept(req: HttpRequest < any > , next: HttpHandler): Observable < HttpEvent < any >> {
 this._spinnerService.requestStarted();
 return next.handle(req).do(
   (event: HttpEvent<any>) => {
     if (event instanceof HttpResponse) {
       this._spinnerService.requestEnded();
     }
   },
   (err: any) => {
     if (err instanceof HttpErrorResponse) {
       this._spinnerService.requestEnded();
     }
   }
 );
}

LOGIN:

login() {
this.spinnerSub = this.spinnerService.spinnerState.subscribe(state => {
  this.showSpinner = state;
});
   const user = {
     email: this.userEmail,
     password: this.userPw
   };

   this.authService.authenticateUser(user).subscribe((data: ILoginResponse) => {
     this.spinnerSub = this.spinnerService.spinnerState.subscribe(state => {
        this.showSpinner = state;
     });
     if (data.success) {
      this.notificationService.showSuccess(data.title, data.message)
        .then((result) => {
          console.log(result);
          this.router.navigate(['/user/dashboard']);
        })
        .catch((reason) => {
          console.log('--> Alert dismissed: ', reason);
        });
     } else {
       this.notificationService.showError(data.title, data.message)
        .then((result) => {
          console.log(result);
        })
        .catch((reason) => {
          console.log('--> Error dismissed: ', reason);
        });
     }
   });
  }

NOTIFICATION SERVICE:

  showSuccess(type, message) {
   return swal({
    title: 'Success',
    text: message,
    type: type
   });
  }

  showError(type, message) {
    return swal({
      title: 'Error',
      text: message,
      type: type
    });
  }

Any help/suggestion would be much appreciated. Thanks.

EDIT: I tried putting the NotificationService, specifically the showError() in the (err:any) block of the Interceptor. Well it works but I want to keep the NotificationService on specific components (like Login), not every requests.

Upvotes: 0

Views: 690

Answers (2)

Dmitry Grinko
Dmitry Grinko

Reputation: 15204

Change your code

login() {
    this.spinnerSub = this.spinnerService.spinnerState.subscribe(state => {
        this.showSpinner = state;
    });
    const user = {
        email: this.userEmail,
        password: this.userPw
    };

    this.authService.authenticateUser(user).subscribe((data: ILoginResponse) => {
        this.spinnerSub = this.spinnerService.spinnerState.subscribe(state => {
            this.showSpinner = state;
        });
        console.log('My data:', data);
        this.notificationService
            .showAlert(data.title, data.message, 'success', res => {
                console.log(res);
                this.router.navigate(['/user/dashboard']);
            });
    }, error => {
        console.log('My error:', error);
        this.notificationService
            .showAlert(err.title, err.message, 'error', res => {
                console.log(res);
            });
    });
}



showAlert(title: string, message: string, type: string, callback?: any) {
    return swal({
        title: title,
        text: message,
        type: type
    }).then(() => {
        if(callback) {
            callback(message);
        }
    });
}

Upvotes: 1

Chau Tran
Chau Tran

Reputation: 5088

The flow of the Interceptor is to prevent faulsy response coming back from a RestAPI call.

For example in my question above, I check data.success because that is how I set up in my Backend. The Interceptor will make sure you get a truthy response and whatever is categorized as Error will be set as HttpErrorResponse.

this.authService.authenticateUser(user).subscribe(
 (data: ILoginResponse) => {
 console.log(data);
 this.spinnerSub = this.spinnerService.spinnerState.subscribe(state => {
    this.showSpinner = state;
 });
 this.notificationService.showSuccess(data.title, data.message)
    .then((result) => {
      console.log(result);
      this.router.navigate(['/user/dashboard']);
    })
    .catch((reason) => {
      console.log('--> Alert dismissed: ', reason);
    });
   },

   (err: any) => {
      console.log(err);
      this.notificationService.showError('error', 'Just an error'); <- my NotificationService will 
get called here instead of getting called up in the else block like in my question above.
    });

Upvotes: 0

Related Questions