Route guards leading to incorrect navigation patterns

Having trouble navigating different routes.

I'm working with two separate route modules.

app.routes.ts:

This module contains only the LoginPage:

export const routes: Routes = [
  {
    path: 'login',
    component: LoginPageComponent,
    canActivate: [PreventLoggedInAccess]
  },
  {
    path: '',
    redirectTo: 'login',
    pathMatch: 'full'
  },
  {
    path: '**',
    redirectTo: 'login'
  }
];

export const Routing: ModuleWithProviders = 
    RouterModule.forRoot(routes, { useHash : true });

The PreventLoggedInAccess.canActivate function redirects already logged in users to the `/app/home` section. It's defined as follows:

canActivate(): boolean {
  if (!this._authService.isAuthenticated()) {
      return true;
  }
  this._router.navigate(['/app/home']);
  return false;
}

pages.routes.ts:

This module contains all subroutes under `/app` that are only accessible when the user is logged in. This requirement is met by using

AuthGuardService.canActivateChild
:

export const pageRoutes: Routes = [
  {
    path: 'app',
    component: PagesComponent,
    canActivateChild: [AuthGuardService],
    children: [
      { path: '', redirectTo: 'home', pathMatch: 'full' },
      { path: 'home', component: HomePageComponent },
      { path: 'contents', component: ContentsComponent },
    ]
  }
];

export const Routing: ModuleWithProviders = RouterModule.forChild(pageRoutes);

In this case, any attempt to access an `/app` child route without being logged in will result in a redirect to the login page. The logic is implemented within

AuthGuardService.canActivateChild
:

canActivateChild(): boolean {
  if (this._authService.isAuthenticated()) {
      return true;
  }
  this._router.navigate(['login']);
  return false;
}

Encountered behavior where navigating from `app/home` to `app/contents` requires two attempts for proper redirection to the `ContentsComponent`. On the first navigation, it briefly switches routes before reverting back to `app/home` unless the navigation command is executed twice consecutively. However, transitioning from `app/contents` to `app/home` works smoothly on the first try.

The functionality of `isAuthenticated` and both authguards has been validated. Unauthorized access to any `app` child route triggers a redirect to the login page, while attempting to access `login` when already authenticated results in a redirect to `app/home`.

Further investigation revealed the following flow:

  • First attempt - `app/home` -> `app/contents`:
    • Execute `navigate(['app/contents'])`
    • Invoke `PreventLoggedInAccess.canActivate`
    • Invoke `AuthGuardService.canActivateChild`
  • Second attempt - `app/home` -> `app/contents`:
    • Execute `navigate(['app/contents'])`
    • Invoke `AuthGuardService.canActivateChild`

The expected behavior aligns with the outcome of the second attempt.

EDIT

By removing `this._router.navigate([/app/home]);` from `PreventLoggedInAccess.canActivate`, the issue is resolved:

canActivate(): boolean {
  if (!this._authService.isAuthenticated()) {
      return true;
  }
  return false;
}

However, the question remains: why is `PreventLoggedInAccess.canActivate` triggered when navigating to an `app` child despite `AuthGuardService.canActivateChild` being bound to it? Why does it occur only on the initial attempt?

Answer №1

When it comes to pageRoute, it's important to remember that all subchild of the app can be included in this routing. This means that the routing file should encompass all modules related to the app.

This approach allows for the effective use of lazy loading and guards within the application structure. My response assumes that your pageRoute module is a child of the App.

I would recommend utilizing the AuthGuard only once in the routing setup. It's best practice to apply the AuthGuard to a module containing other modules or components rather than directly on the login component.

In the scenario where the page module is lazily loaded, its activation will depend on the return value of the authguard – true leads to activation while false redirects the user to the login page.

app.route.ts

const routes: Routes = [
  {
    path: '',
    loadChildren: './pages/pages.module#PagesModule',
    canActivate: [AuthGuardService]
  },
  { path: 'login', loadChildren: './login/login.module#LoginModule' },

];

AuthGuard

canActivateChild(): boolean {
  if (this._authService.isAuthenticated()) {
      return true;
  }
  this._router.navigate(['/login']);
  return false;
}

Page.route.ts

const routes: Routes = [
  {
    path: '', component: PageComponent,
     children: [
  { path: '', redirectTo: 'home', pathMatch: 'full' },
  { path: 'home', component: HomePageComponent },
  { path: 'contents', component: ContentsComponent },


     ]
  }
];

To facilitate debugging in the current routing setup, you can utilize Augury from the Chrome web store.

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

Error: Conversion of "2018-01-01-12:12:12:123456" to a date is not possible for the 'DatePipe' filter

<td>{{suite.testSuiteAttributes && suite.testSuiteAttributes.modifiedTimestamp | date: 'yyyy-MM-dd' }} </td> I am trying to display the date in the "05-Feb-2018 11:00:00 PM CST" CST format, but I keep getting an ...

Error in Angular compiler.js at line 2531: Multiple components found for this element, causing template parse errors

After browsing through various topics with a similar issue, I have not found any solutions that address my specific reasons. The problem lies with a standard primeng button component. <div [hidden]="isHidden||isProgramVisible" id="st ...

Learning to render a hexagon on an HTML canvas using TypeScript

After drawing a hexagon on canvas in HTML, I encountered an issue with the translate method. Although it works fine with rectangles, the hexagon does not get translated as expected. To address this problem, I defined the canvas and context elements using ...

Angular5: At what point does Angular finish loading a page?

Within my angular5 application, I have implemented a table that retrieves data from the backend. After the initial load of the table, I aim to adjust the scroll position inside it. To achieve this, I am utilizing the following code: ngAfterViewInit() { ...

Refresh the child component whenever there is a change in the parent's state

As of now, I am in the process of developing a MultiCheckbox Component which looks like this: Checkbox.tsx import './Checkbox.scss'; import React, {ChangeEvent, Component} from 'react'; /* * Description of Checkbox properties */ in ...

What are the best strategies for managing npm dependencies alongside other packages?

I am working on an Angular app that has the following dependencies: "dependencies": { "personalUiLibrary": "1.0.0" }, "devDependencies": { "tailwindcss": "^2.2.7" } In the personalUiLibrary p ...

Error message: Angular material StaticInjectorError - MatDialog provider not found

After trying to launch my Angular 5 page in the browser, I encountered an error message in the console. ERROR Error: StaticInjectorError(AppModule)[AppComponent -> MatDialog]: StaticInjectorError(Platform: core)[AppComponent -> MatDialog]: ...

Arrange Nested Object Array

I've been trying to sort a nested array, but I'm having trouble with it. It works when I specify the index, but that's not ideal...I need to loop through all values. Array items= [{ app_type_id: 1, apps: [{ app_id: 3, ...

Guide to setting up form data with asynchronous data

Greetings, experts! I have developed a web service using React. Now, I am looking to create a page for modifying user information. Although I can successfully receive user data and set it as the value of inputs, I am encountering a warning in React. ...

Angular paginator encountered an issue while attempting to parse the template

I'm updating my data list to include pagination, and everything seems fine with retrieving data and sorting. However, when I add the paginator tag to my template, Angular shows me an error: ERROR in Errors parsing template: Unexpected closing tag " ...

Unleashed Breakpoint Mystery in Ionic 5 Angular with VSCode

I recently upgraded my Ionic 5 Angular 12 app from Ionic 4 Angular 8. The application is working well and remains stable, but I have encountered some issues while debugging. Firstly, when I use the launch.json file in Visual Studio Code to run the app, it ...

I encountered an error when trying to install '@angular/cli' using the command 'sudo npm install -g @angular/cli' on Ubuntu

Encountering a problem while attempting to install Angular-CLI on Ubuntu My current Node.js and npm versions are as follows: Node-v9.11.1 npm - 5.6.0 The command I ran was: savera9@savera9-desktop:~$ sudo npm install -g @angular/cli Howev ...

What is the method for retrieving all documents that contain an array field with at least one object-element having a property value of 'X'?

I have a collection of MongoDB documents structured like this: { "group": "P32666", "order": [{ "_id": { "$oid": "5e8e9b40e7999f6b90fd88bf" }, "name": "Dmitriy A", "login": "example", "password": "example", "email": "exampl ...

Tips for accurately mapping JSON from an Angular 5 POST request to a Java entity with RestEasy integration

Below is code snippet from an Angular 5 component: export class TripsComponent implements OnInit { ... ... addTrip() { let newTrip = new Trip(this.new_trip_name, this.new_trip_description, this.company); this.tripService.addTrip(newTrip).t ...

Press the second form submit button after the completion of another Observable

Below is the unique process we aim to accomplish using solely RXJS Observables: Press Login button (form with username & password). We bind Observable.fromEvent with our form. Upon submitting the form, call loginUser() to send an http request to serv ...

Collaborating ASP.NET MVC and WebAPI token sharing

Within my ASP.NET MVC and Angular2 application, I rely on Identity Server 3 for user authentication. The usual process involves users logging into the MVC application, which then saves the token in a cookie. Once logged in successfully, users can perform ...

Exploring the Issue with SWR Hook in Next.js using TypeScript

Seeking assistance with the SWR hook as I navigate through some challenges while attempting to use it effectively. This time, the issue appears to be minor. The objective is to set a breakpoint in my API to retrieve data, using axios. The problem arises ...

Are there inline type assertions in Typescript that function similarly to assertion functions?

Having a good understanding of assertion functions and other inline forms of type assertions in TypeScript, I have two interconnected questions. Firstly, why do they not provide the same level of assertion to TypeScript? Secondly, is there a way to achieve ...

Tips for updating a component when the route changes while remaining on the same component

Currently, I am facing a challenge in my Angular 4 project. The issue revolves around a two-step booking form used for scheduling appointments. Specifically, I have two distinct industries - Industry A and Industry B. In the midst of booking an appointment ...

What methods does Angular use to determine the parameter types of a constructor?

I've been experimenting with replicating Angular's approach to interpreting the constructor in an injectable service. function Injectable() { return function<T extends { new (...args: any[]): {} }>(con: T) { return class extends con ...