How can I resolve the infinite loop issue caused by Angular Auth guard when using routing?

My current struggle lies within the authentication guard logic and routing setup.

In my app-routing.module.ts file, I have defined 3 routes:

const routes: Routes = [
  {
    path: '',
    loadChildren: () => import('./browse/browse.module').then(m => m.BrowseModule),
  },
  {
    path: AppRoutes.auth,
    loadChildren: () => import('./auth/auth.module').then(m => m.AuthModule)
  },
  {
    path: AppRoutes.landing,
    loadChildren: () => import('./landing/landing.module').then(m => m.LandingModule),
  },
];

One of these paths leads to the '' route which sends users to the BrowseModule at /browser.

Within the browser-routing.module.ts, I've implemented an AuthGuard that redirects users to the landing page if they are not authenticated:

const routes: Routes = [
  {
    path: '',
    component: BrowseComponent,
    redirectTo: BrowseRoutes.browse,
  },
  {
    path: BrowseRoutes.browse,
    loadChildren: () => import('./home/home.module').then(m => m.HomeModule),
    canActivate: [AuthGuard]
  }
];

AuthGuard.ts :

  canActivate(
    route: ActivatedRouteSnapshot
  ): Observable<boolean> | Promise<boolean> | boolean {
    if (this.authService.hasToken()) {
        if(this.authService.isAuthenticated()){
          console.log('logged in guard');
          this.router.navigate(['browse']);
            return true;
        } else {
          console.log('not logged in guard');
            this.router.navigate(['landing']);
            return false;
        }
    } else {
      console.log('no token not logged in guard');
      this.router.navigate(['landing']);
      return false;
    }


  }

The issue at hand is :

When I am logged in, there seems to be an infinite loop occurring with the AuthGuard. It continuously prints either "not logged in" and cycles between "/" and "/browse", or it shows "logged in" and enters an infinite loop once more. How can this be resolved?

Answer №1

When the condition is met, there is no need to navigate away from the guard. By doing so, the guard takes control of a decision it shouldn't be responsible for, limiting its reusability for other paths as it will always redirect to /browse. The guard's role is to validate and should only navigate when a condition is not satisfied.
Your canActivate method should follow this structure:

if (isLoggedIn()) {
  return true;
}
this.router.navigate(['landing']);
return false;

Answer №2

Optimizing Angular Routing Referencing the official Angular documentation on routing at "https://angular.io/guide/router"

The order in which routes are configured plays a crucial role due to the first-match wins strategy employed by the router. This means that more specific routes should be prioritized over less specific ones. In the provided configuration, routes with static paths are listed before an empty path route, which serves as the default route. The wildcard route is placed last as it acts as a fallback only when no other routes match.

It appears that your current route consistently matches the first route 'browser.module', following Angular's 'first-match wins' principle.

To optimize this, consider rearranging your routes as shown below:

const routes: Routes = [

  {
    path: AppRoutes.auth,
    loadChildren: () => import('./auth/auth.module').then(m => m.AuthModule)
  },
  {
    path: AppRoutes.landing,
    loadChildren: () => import('./landing/landing.module').then(m => m.LandingModule),
  },
  {
    path: '',
    loadChildren: () => import('./browse/browse.module').then(m => m.BrowseModule),
  },
];

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

Trying to toggle between two Angular components within the app component using a pair of buttons

Currently, I am developing an application that requires two buttons to display different nested apps. Unfortunately, I am unable to use angular routing for this particular design. These two buttons will be placed within the app.component. When Button A i ...

Mastering the use of SVG icons in Angular 4+: A comprehensive guide

I have an icon.svg file with a collection of icons that I would like to use in my app, similar to how we display material icons. Does anyone have any ideas on how to include the file in the app and use these icons? I've tried looking for solutions a ...

Whenever I attempt to run the NPM install command in the Terminal, it seems to generate multiple errors

I am encountering an issue on my work laptop. I have the latest versions of Angular, Nodejs, Nodesass, and VScode installed in the local environment path. Whenever I download an Angular template from Github and try to do NPM Install, it consistently thro ...

Tips for handling a function only after the model window has returned a promise in Angular 2

When a button is clicked, three functions are called in sequence within a promise. The first function is responsible for blocking a model window and returning a promise which then resolves the next function. The HTML code snippet is as follows: ...

Can a new class be created by inheriting from an existing class while also adding a decorator to each field within the class?

In the following code snippet, I am showcasing a class that needs validation. My goal is to create a new class where each field has the @IsOptional() decorator applied. export class CreateCompanyDto { @Length(2, 150) name: string; @IsOptional( ...

Steps to implement the click functionality on the alert controller and modify the language in Ionic 4

I am currently developing a multilingual Ionic 4 app and have implemented the alert controller to display language options. However, I am facing an issue on how to dynamically change the language based on user selection. Below is my app.component.ts code ...

I am looking to transfer information from Angular 4 to Java servlet (cross-domain)

Having trouble sending data from Angular 4 to a Java servlet due to access control restrictions. Need to figure out how to properly insert data into the database using the Java servlet. Here is my code snippet: import { Injectable } from '@angular/ ...

Unable to fetch packages from npm or github using jspm install because of proxy configuration restrictions

I'm attempting to execute a basic Angular 2 unit test application. I have cloned the following git repository and followed the steps provided in the readme file: https://github.com/matthewharwood/Hit-the-gym I have configured proxy settings for npm, ...

Can someone guide me on configuring Material-UI DataGrid in React to have multiple headers with column span?

Is there a way to achieve multiple headers with column span in the Material-UI DataGrid component? view image example ...

Exploring multiple states within an interval function in React Native

I'm struggling to find the right words for this question. I've encountered an issue where I need to constantly check and update a complex state object within an interval loop in my program. To simplify, let's say it consists of just a counte ...

Creating a reusable field for reactive forms in Angular: A step-by-step guide

I need assistance with creating a versatile field component for reactive forms, but I am facing challenges in retrieving the value from the custom-input element. <form [formGroup]="form" (ngSubmit)="submit()"> <custom-input i ...

What is the correct way to handle Vue props that include a dash in their name?

I am currently working on a project using Vue. Following the guidelines of eslint, I am restricted from naming props in camel case. If I try to do so, it triggers a warning saying Attribute ':clientId' must be hyphenated. eslint vue/attribute-hyp ...

Mastering the Type Model on Firestore Function to Retrieve Field ValuesUnlock the potential of the Type

When retrieving data from Firestore, I am able to print the entire object using doc.data. However, I am having trouble accessing the specific value of unixtime as it is coming through as undefined. I need help in correctly applying my type model so that I ...

Using Vue.js, learn how to target a specific clicked component and update its state accordingly

One of the challenges I'm facing is with a dropdown component that is used multiple times on a single page. Each dropdown contains various options, allowing users to select more than one option at a time. The issue arises when the page refreshes afte ...

Bundling and minifying Angular2 assets

In the world of ASP.NET (or gulp), bundling and minification are taken care of. However, a different issue arises when following Angular2 tutorials: the view HTML is typically embedded within the component itself. Fortunately, there is a way to separate th ...

Separate configurations for Webpack (Client and Server) to run an Express app without serving HTML files

I am currently developing an application with a Node Backend and I am trying to bundle it with Webpack. Initially, I had a single Webpack configuration with target: node. However, I encountered issues compiling Websockets into the frontend bundle unless I ...

Adding or subtracting values in Angular framework to manipulate numbers

I am looking to increment a number from 1 to 50. I attempted to use the following code, but unfortunately the function is not working properly. See Demo Here Here is the HTML: <Button text="+" (tap)="plus()"></Button> <Button text="-" (t ...

What types should be used when passing a NgRx Action as a parameter to a function?

Within my Effects function, I have implemented the following code structure. I have included a few lines of code for the catchError block to ensure that: Any errors are handled by the state/store The errors are forwarded to the global error handler / Int ...

When incorporating pinia with Vue, encountering an error with the decorator that says "Error: Unable to access 'useCoreStore' before initialization" may happen

While implementing the vue-facing decorator in my current project, I encountered an issue with setting up pinia. The structure of my component resembles the example provided here: I have verified that decorators like @Setup are functioning correctly, ind ...

Transferring data between pages in Next JS using App Route and Typescript

Seeking assistance to extract data from an array on one page and display it on another page. I am working with NextJs, Typescript, and AppRoute. Code in app/page.tsx: import Image from 'next/image' import Link from 'next/link' const l ...