What steps should be taken to automatically redirect to a different page upon encountering an HTTP error?

In my Angular project, I've integrated the following code within a class that extends Angular's HttpInterceptor:

handleError(error: unknown): Promise<boolean> {
        if (error instanceof HttpErrorResponse) {
            return this.router.navigate([NOT_FOUND_URL, this.errorDescriptionProvider.getHttpErrorDescription(error)]);           
        }
        else
            return this.router.navigate([NOT_FOUND_URL, this.errorDescriptionProvider.getUnspecifiedNetworkErrorDescription()])
    }

and also this:

intercept(req: HttpRequest<T>, next: HttpHandler): Observable<HttpEvent<unknown>> {
    const stream =  next
        .handle(req)
        .pipe
        (
           catchError(x => from(this.handleError(x)))              
        );

        //Encountering an error stating that it is not assignable to Observable<HttpEvent<unknow>> due to its type being Observable<boolean |....>
        return  stream;
}

What's the best way to achieve automatic redirection on HTTP errors?

Answer №1

If any unauthorized requests are made, they will be redirected to the Login page.

import { HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Observable } from "rxjs/Rx";
import { Router } from "@angular/router";
import { tap } from "rxjs/internal/operators";


@Injectable()
export class UnAuthorizedInterceptor implements HttpInterceptor {
  constructor(private router: Router) { }
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(request).pipe(tap(() => { },
      (err: any) => {
        if (err instanceof HttpErrorResponse) {
          if ((err.status === 401) || (err.status === 403)) {
            this.router.navigate(['/login']);
          } else {
            return;
          }
        }
      }));
  }
}

Add

{ provide: HTTP_INTERCEPTORS, useClass: UnAuthorizedInterceptor, multi: true }
as a provider in app.module.ts file

Answer №2

If you need to redirect to an error page in your Angular application, simply inject the Router into your service and use navigate.extra to send the data along.

A helpful service

  getData()
  {
    return throwError({error:"NotExist"}).pipe(catchError(x=>{
      return this.error(x)
    }))

  }
  error(x):Observable<any>
  {
    console.log(x)
    this.router.navigate(['/error'],{ state: { error: x } })
    return of(null);
  }

Your error.component

@Component({
  selector: 'error',
  template: `<h1>ERROR</h1>
  <pre>{{ state$ | async | json }}</pre>
  `,
  styles: [`h1 { font-family: Lato; }`]
})
export class ErrorComponent implements OnInit  {
private state$: Observable<object>;

  constructor(public activatedRoute: ActivatedRoute) { }
    ngOnInit() {
      this.state$ = this.activatedRoute.paramMap
      .pipe(map(() => window.history.state))
  }

}

Check out the updated sample on StackBlitz

Answer №3

To ensure smooth navigation, adjust your handleError function to have a return type of void.

Additionally, in the catchError block:

  catchError(err => {
    if (err instanceof HttpErrorResponse) {
      //invoke your handle error function
       handleError(err);
    }
    return throwError(err);
  }),

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Guide to implementing real-time filtering for a table through user input in a text box

https://i.stack.imgur.com/6DTAb.jpgI have a task to complete for an assignment. The assignment requires implementing client-side filtering of data as text is entered in a text box. I need guidance on how to implement it. Below is the problem statement for ...

Is there a way to inject a parent component into a shared directive without explicitly stating the component type?

Is there a way to specify my directive so that it can be utilized in all components? my directive.ts : import { Parent } from '../../_common/Parent'; declare var jQuery: any; @Directive({ selector: '[icheck]' }) export class Ichec ...

Disabling the background shadow effect in Angular Material's Accordion

I successfully disabled the background shadow on the Angular Material Accordion in this demonstration by incorporating the following CSS rule: .mat-expansion-panel:not([class*='mat-elevation-z']) { box-shadow: none !important; /* box-shadow: ...

"Using Angular's NgFor directive to efficiently organize and collapse data within

I am currently working on displaying API data in a table using ngFor, and I am facing an issue with hiding/showing a specific row of details outside the ngFor loop. Since this line is not within the ngFor loop, I am unable to bind the data accordingly. Can ...

Incorporating an Angular Application into an Established MVC Project

I am working on an MVC project within an Area of a larger solution. My goal is to incorporate an Angular App into this area and integrate it with my MVC project. The catch is that this is not a .Net Core Mvc project. How can I configure my project to utili ...

A guide to sorting through in-app notifications in REACT-NATIVE based on their read status

Incorporating two headings, "Unread" and "Read", into the notification system is my goal. When opened, the Unread Notifications should be displayed beneath the Read notifications. This data is being retrieved from an API. Each notification contains a key ...

What is the best way to programmatically set attributes on an HTML element or include HEAD/(LINK|TITLE) elements in Angular?

As I work on my Angular 12 application, I am facing the challenge of making it compatible with both LTR and RTL languages such as English and Arabic. This compatibility needs to be user-selectable within the application. Bootstrap, which provides the UI st ...

Troubleshooting column alignment with Bootstrap4 and Angular: Resolving issues with text alignment on

Being relatively new to Bootstrap 4, as I have only used version 3.3 on my previous project which did not utilize the flexbox grid system. Now that I am embarking on a new project, I find myself facing a challenge: I am struggling to apply the "text-alig ...

Angular initiates the creation of cross-origin HTTP requests

I am currently in the process of revamping an old android application to transform it into an ionic2 platform in order to develop a cross-platform app. Previously, in the android app, I utilized Jsoup with this specific call: Jsoup.connect(url).get(); It ...

Expanding Generic Interfaces in Typescript

I am working on a project where I need to enhance a typescript type by adding a new property in order to extend a generic type. To achieve this, I plan to define a Confidence<any> type that has the following structure: export interface Confidence< ...

Enable a VueJS directive on-the-fly from a separate directive

My goal is to simplify the process of binding a form control to vuejs by creating a directive that handles all necessary events for tracking changes in a form field. Rather than manually adding multiple event listeners like this: <input type="text" na ...

In Angular, there is a situation where two input fields are both referencing the same event.target

I am facing an issue where I have two input fields that are linked to the same event.target.value object, but I want them to be separate. <form class="flex-list" [formGroup]="calculation_Input" (input)="input($eve ...

The compatibility between TypeScript and the Node.js crypto module is currently not fully optimized

Incorporating encryption into my project using vuejs and typescript has been a challenge. I managed to implement it in the .vue file successfully, but encountered an issue when trying to write the encryption into a typescript class. The mocha test runs fin ...

The futuristic async-routing capabilities of Angular 2.0.0-rc1

As of the latest updates in May 2016 (RC1), the new syntax is @Routes instead of @RouteConfig. Previously, you would have used newAsyncRoute to asynchronously load components. The official documentation on Angular.io is still not available. Does anyone kn ...

Leveraging Angular 4-5's HttpClient for precise typing in HTTP requests

Utilizing a helper service to simplify httpClient calls, I am eager to enforce strong typing on the Observable being returned. In my service where I utilize the api Service and attempt to obtain a strongly typed observable that emits: export class ApiU ...

Is there a different way to access the prohibited secure route?

I am interested in finding an alternative path for the router displayed below. Specifically, I am wondering if it is possible to set a different route (such as /) in case the AdalGuard restricts access to route /int or any of its sub-routes? Traditionally ...

Using Angular's ElementRef to set focus on an ion-textarea: "The 'setFocus' property is not found on the 'ElementRef' type."

After developing a textarea component that automatically focuses itself when created using the ngAfterViewInit() method, everything seemed to be working perfectly as expected. ngAfterViewInit() { if(this.text.length===0){ this.theinput.setFocus(); ...

What is the process of extracting multiple attributes from an object that has been selected by a user using mat-options (dropdown list) in Angular?

Summary: A dropdown list contains objects, unsure how to capture multiple attributes of selected object. Current Implementation: I have successfully created a dropdown list that displays the details of an object retrieved through an API call: <mat-f ...

Typegoose and NestJS: The 'save' property is not found on this type

I recently started using typegoose and nestjs for my backend-server. In my pages.service.ts file, I already have a function called getPageById() to retrieve a single page by its ID. However, when trying to call this function from another function within th ...

Using Angular5 to extract coordinates from the Google Maps v3 API when a map "click" event occurs

Can anyone assist me with retrieving coordinates from a click event on a map? Here is the desired result: Link Below is the code I have so far: import { Component, OnInit } from '@angular/core'; import { ViewChild } from '@angular/core&ap ...