Encounters a hiccup when trying to load a component while not being logged in

I encountered an issue with redirection when a user is not logged in. In my project, I have two Guards for the Admin and User roles. I am using functions from the @angular/fire/auth-guard library to handle redirection based on the login status. However, when I add my custom guards along with the built-in ones, the guard that checks if a user is logged in or not stops working properly and causes the page to keep loading indefinitely. Here's an example of the code:

In the code snippet below, both RolUserGuard and RoleAdminGuard are functioning correctly, but the AuthGuards for home and admin components are causing the pages to load endlessly without redirecting to the login page. On the other hand, when a logged-in user tries to access the login page, the AuthGuard works as expected.

const redirectUnauthorizedToLogin = () => redirectUnauthorizedTo(['']);
const redirectLoggedInToHome = () => redirectLoggedInTo(['home']);

const routes : Routes = [
  {path : '',redirectTo: 'login', pathMatch: 'full'},
  {path : 'login', component : LoginComponent, canActivate: [AuthGuard], data: {authGuardPipe: redirectLoggedInToHome}},
  {path : 'home', component : HomeComponent, canActivate: [AuthGuard,RoleUserGuard], data: {authGuardPipe: redirectUnauthorizedToLogin} },
  {path : 'admin', component : AdminComponent, canActivate: [AuthGuard,RoleAdminGuard], data: {authGuardPipe: redirectUnauthorizedToLogin}, children:[
    {path : '', component : AdminUsersComponent},
    {path : 'user/:id', component: DetailsComponent}
  ]},
  {path : '**', component: PageNotFoundComponent}
]

Could there be an error in my implementation? Is it possible that the issue lies with the data property, causing conflicts when multiple Guards are added? Any insights would be appreciated.

Below is the code snippet for the other guards, which follows a similar structure with minor differences:

  canActivate( route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
    
    const rol = localStorage.getItem('rolUser');

    if(rol!=='admin'){
      this.router.navigate(['/home']);
      return false;
    }

    return true;
  }

Answer №1

In order to address this issue, I suggest removing the authGurad and utilizing the UserService in each guard to verify if the user is logged in:

For the RoleAdminGuard:

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    const isLoggedIn = this.userService.isLoggedIn();
    if (!isLoggedIn) {
      this.router.navigate(['/login']);
      return false;
    }
    const rol = localStorage.getItem('rolUser');

    if (rol !== 'admin'){
      this.router.navigate(['/home']);
      return false;
    }

    return true;
}

A similar approach can be taken for RoleUserGuard with different role conditions.

Alternatively, we can utilize a user dictionary within the UserService.
UserService:

userAccess= {
  home: 'user',
  admin: 'admin'
}

This allows for the usage of a single guard (RoleGuard)
RoleGuard:

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    const isLoggedIn = this.userService.isLoggedIn();
    if (!isLoggedIn) {
      this.router.navigate(['/login']);
      return false;
    }
    const rol = localStorage.getItem('rolUser');
    const userAccess = this.userService.userAccess[next.url]
    if (rol !== userAccess) {
      const navigateTo = rol === 'admin' ? '/admin' : '/home';
      this.router.navigate([navigateTo]);
      return false;
    }

    return true;
}

I trust that these suggestions will assist you in resolving the matter at hand.

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

How to resolve TypeScript error TS2322 when a function returns an interface

export interface AWSTags { CreatedBy: string; Environment: EnvironmentMap; Name: string; OwnedBy: string; Platform: string; Product: string; Runbook: string; Service: string; } Another script contains the following function to generate an ...

Capture Video on iOS devices using the MediaRecorder API and display it using HTML5 Video Player

Issue: I am facing an issue where I cannot record video or get a video stream from the camera on iOS through my Angular web application built using ng build. Investigation: In my investigation, I explored various websites that discuss Apple iOS features ...

Enhance the appearance of an angular custom component with unique styling

I have developed a unique custom angular element called my-component and in its stylesheet I've added the following: :host { display: inline-block; width: 55px; } Now, when using my-component in another component's template, I tried to ...

Establish a spacing between a pair of geometries in THREE.JS

I need assistance with adjusting the distance between cylinders and sprites generated by this code. What steps can I take to achieve this? const THREE = this.context.three; const textureLoader = new THREE.TextureLoader(); const geometr ...

Is it advisable to prevent Set and Map from having unspecified generics in TypeScript?

Upon reviewing some old code that I wrote, I realized that I had neglected to specify a generic type for a Set. The type was set as Set<unknown>. Strangely, despite this, I found that I could still utilize all the methods of the Set without encounter ...

Guide to incorporate a URL handler for a static HTML page in the app.yaml file while running an Angular application

I'm currently in the process of setting up a static HTML page to be displayed after a user unsubscribes from a mailing list. This page needs to be hosted on the same Google App Engine as my primary Angular 7 application. However, when I try to access ...

Can you explain the purpose of the "let-" attribute in Angular 6?

The ng-bootstrap modal documentation showcases the use of a unique attribute like let-*, which is utilized to link a function or event for later reference. By examining the (click) events and the let-c / let-d attributes in the examples, one can understand ...

Using TypeScript with React and Redux to create actions that return promises

Within my React application, I prefer to abstract the Redux implementation from the View logic by encapsulating it in its own package, which I refer to as the SDK package. From this SDK package, I export a set of React Hooks so that any client can easily u ...

Can anyone tell me the best way to access the name attribute of an HTML element in TypeScript?

Currently, my code is utilizing the name attribute to verify whether the user has entered information in a specific field and validating the input. However, I am facing an issue where the submit button remains active even if there are empty fields presen ...

What are the best scenarios for creating a constructor in Angular 2 using Typescript?

Check out these sample constructors I found in the Angular 2 documentation: export class AppComponent implements OnInit { title = 'Tour of heroes'; heroes: Hero[]; selectedHero: Hero; constructor(private heroService: HeroService ...

Is there a workaround in TypeScript to add extra details to a route?

Typically, I include some settings in my route. For instance: .when('Products', { templateUrl: 'App/Products.html', settings: { showbuy: true, showex ...

Error encountered during Svelte/Vite/Pixi.js build: Unable to utilize import statement outside of a module

I'm currently diving into a project that involves Svelte-Kit (my first venture into svelte), Vite, TypeScript, and Pixi. Whenever I attempt to execute vite build, the dreaded error Cannot use import statement outside a module rears its ugly head. Desp ...

Searching for variables in Angular environments

Incorporating environment variables into my Angular app via the CI/CD pipeline is something I'd like to do. This would allow for automatic configuration of both environment.ts and proxy.config.json. For instance, export const environment = { var: $ ...

Modifying tooltip format in React ApexChart from dots to commas

I am in the process of creating an app targeted towards German users, who traditionally use commas (20,00) instead of dots (20.00) for numbers. I am using react-apexcharts and struggling to figure out how to replace the dots with commas in both my chart an ...

What is the process for coding a prototype-based ES5 class in TypeScript?

Currently, I am in the process of migrating some legacy ES5 projects to TypeScript. These projects contain older-style classes (functions) defined as shown in the simplified examples below: function MyClass(arg1) { this.arg_prop_1 = arg1; this.arg_prop ...

Setting a condition for a function call when a checkbox is clicked

My table has columns labeled NoBill and Bill, with checkboxes as the values. Here is the default view of the table: https://i.stack.imgur.com/ZUvb2.png When the checkbox in the NoBill column is clicked, the total value (this.total) is calculated. The t ...

Error: Model attribute missing in Adonis JS v5 relationship

Recently, I started diving into the Adonis framework (v5) and decided to build a todo list api as part of my learning process. However, I'm facing an issue concerning the relationship between the User and Todo entities. Let me show you the models fo ...

Opting out of notifications using Angular's NGXS

I'm new to NGXS in Angular and have recently learned that you don't need to manually unsubscribe when using the async pipe. However, I am currently subscribing to both query parameters and dispatched actions. Do I still need to manually unsubscri ...

Set a parameter for my AppComponent during the Bootstrap process

Currently, I am working on an Angular version 7 app that is being hosted within an ASP.NET application. My goal is to have a dropdown in the .NET app and use the selected value to call the Angular app. I've made numerous attempts to pass a parameter d ...

What is the initial component that Angular will activate or run?

Uncertainty surrounds the correctness of my question. Within my application, there exist numerous routing components and feature modules. I am eager to discern whether the appcomponent.ts file or the routing logincomponent.ts file will be executed first. ...