Why is the guard not safeguarding the root route and only protecting its children?

I have a routing setup with 3 specific routes:

const routes: Routes = [
  {
    path: '',
    component: DashboardComponent,
    canActivate: [AuthGuard],
    children: [
      {path: 'products', component: ProductsListComponent},
      {path: 'orders', component: OrdersListComponent}
    ]
  }
];

@NgModule({
  imports: [
    RouterModule.forChild(routes)
  ],
  exports: [
    RouterModule
  ]
})
export class DashboardRoutingModule {
}

However, the AuthGuard currently only protects the child routes, products and orders. It is essential to also protect the root route /.

UPDATE 1 for AuthGuard

@Injectable()
export class AuthGuard implements CanActivate, CanActivateChild {
  constructor(private authService: AuthService, private router: Router) {
  }

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    if (this.authService.isLoggedIn) {
      return true;
    } else {
      this.router.navigate(['/login'], {
        queryParams: {
          accessDenied: true
        }
      });
      return false;
    }
  }

  canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    return this.canActivate(childRoute, state);
  }
}

And here is the AuthService:

@Injectable()
export class AuthService {

  private loggedIn = false;

  get isLoggedIn() {
    return this.loggedIn;
  }

  constructor(private router: Router) {
  }

  login(user: User) {
    this.loggedIn = true;
    window.localStorage.setItem('user', JSON.stringify(user));
    this.router.navigate(['/products']);
  }

  logout() {
    this.loggedIn = false;
    window.localStorage.clear();
    this.router.navigate(['/login']);
  }
}

Answer №1

To properly configure your AuthGuard, you must ensure it includes both the CanActivate method for the parent and the CanActivateChild method for its children.

@Injectable()
export class AuthGuard implements CanActivate, CanActivateChild {
  constructor(private authService: AuthService, private router: Router) {}

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
      let url: string = state.url;

      return this.check(url);
  }

  canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
      return this.canActivate(route, state);
  }
}

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

Generate an alert with a numerical input field - Ionic

How can I create an input with type number in AlertController? I attempted to implement this, but the input only accepts text and not numbers. const alert = this.alertCtrl.create({ title: 'Add Ingredient', inputs: [ { name: ' ...

Utilizing Angular 2 to Access APIs with Basic Security Authentication

I am attempting to make a call to an HTTP method implemented with ASP Web API from an Angular 2 client. However, I am encountering the following error: OPTIONS 401 (Unauthorized) XMLHttpRequest cannot load . The response to the preflight request does no ...

What is the best way to utilize the typescript module for detecting and managing typescript errors and warnings in your code?

Currently, I am experimenting with the typescript module to programmatically detect typescript errors. Below is a simplified version of what I have been working on: var ts=require('typescript') var file_content=` interface Message{ a:string ...

Combining types: unable to utilize the second optional type within a for loop

I am facing an issue while looping through an array due to the union type. I am wondering what I have overlooked in the code below that is causing Visual Studio Code to not recognize the second optional type for that specific array. class Menu { // name ...

Incorporating New Relic into an Angular Universal application running on Node.js

I am in the process of integrating newrelic into my node.js application, which is built with angular universal and bundled using webpack. The first line in main.server.aot.ts reads: const newrelic = require('newrelic'); In addition, I have inc ...

Is it possible to assign a name to an implied return type?

Imagine having a function like this: function fetchUser() { return { username: "johndoe", email: "johndoe@example.com" } } You can create a type based on the return value: type User = ReturnType<typeof fetchUser>; But, when you hover ov ...

Navigating through template files in Angular 2 components

Currently, I am working on developing a top-level component that requires an input of type @Input(): Object. This object needs to contain an array of components, which will be iterated through using *ngFor, and the templates of these components must be p ...

I am encountering an issue regarding the 'endpoint' property within my environment.ts file while working on an Angular 17 project

My goal is to incorporate the property endpoint from my environment.ts file into my service: export const environment = { production: false, endpoint: 'http://localhost:3000/api/cabin/' }; This snippet showcases my service: import {Injectabl ...

Creating a React Native project without the use of TypeScript

Recently I dived into the world of React Native and decided to start a project using React Native CLI. However, I was surprised to find out that it uses TypeScript by default. Is there a way for me to create a project using React Native CLI without TypeS ...

What is the best way to retrieve all the keys from an array?

I am looking to retrieve the address, latitude, and longitude data dynamically: let Orders= [{ pedido: this.listAddress[0].address, lat: this.listAddress[0].lat, lng: this.listAddress[0].lng }] The above code only fetches the first item from the lis ...

Include a condition to verify the values

Looking to enhance the code by incorporating an if or switch case: The initial code snippet is as follows: {(errorMessage || invalidEmailError.length > 0) && ( <Message type="error" className="mt-l" ...

The variable 'React' is defined but not utilized in the code

Here's the code snippet in question: // tslint:disable import * as React from 'react'; import { Input, InputProps } from '../atoms/Input/Input'; import { FormControl } from '../hoc/FormControl/FormControl'; export const ...

What is the reason behind a TypeScript compiler error being triggered by an 'if-else' statement, while a ternary operator construct that appears identical does not raise any errors?

My function is designed to either return a value of IDBValidKey or something that has been converted to IDBValidKey. When I use the ternary operator to write the function, it works fine. However, if I try to write it as an if-else statement, it causes a co ...

A guide to efficiently removing an element in Angular using TypeScript by considering certain properties

I need help removing an element from an array based on any property such as its key, name, or email. HTML <tr *ngFor="let person of persons;" (click)="remove(person.key)"> <td>{{person.key}}</td> <td>{{person.name}}</td> ...

With a single click, Clickaway is triggered not once, but twice

I am working on creating a filter component where I can pass filter options down to my child component. Each filter has a click event to open the filter for user selection, as well as a v-on-clickaway event that closes the options when the user clicks away ...

Add up values from a reducer using two distinct actions

I have implemented ngrx-store in my project and created a reducer that handles two different actions. Each action contains the number of task count as payload. Now, I want to sum up the numbers from both actions when they are emitted. When I dispatch thes ...

Angular: The dilemma of choosing between updating individual properties or reassigning objects

I am currently working with an object structure that looks like this: steps:any = [ { id: 1, name: "A", next: [{ id: 2, name: "B" }, { id: 3, name: "C" }] }, { id: 2, name: "B", next: [{ id: 1, name: "B" }] }, { ...

Developing a Typescript npm package

In my project, there is a directory called models (named my-models) which houses several important typescript classes for my application. While I have been able to use these classes within the app without any issues, I now wish to turn it into an npm pack ...

Dealing with inconsistent wait problems in Angular applications with Protractor and Jasmine

In my current project, I am using Angular for building the application along with Protractor and Jasmine for e2e tests. However, we have been experiencing inconsistent test script failures during execution. To tackle this issue, we tried setting ignore.s ...

What is the best approach to create a regex pattern that will identify variables enclosed in brackets across single and multiple lines?

In my Typescript project, I am working on matching all environment variables that are de-structured from process.env. This includes de-structuring on both single and multiple lines. Consider the following examples in TS code that involve de-structuring fr ...