Disabling the Angular router link

I'm currently working on an Angular application that utilizes routing and auth guards.

Check out the code on StackBlitz

View the app component HTML here

<div class="container">
  <div class="row">
    <div class="col-xs-12 col-sm-10 col-md-8 col-sm-offset-1 col-md-offset-2">
      <ul class="nav nav-tabs">
        <li role="presentation" routerLinkActive="active"
        [routerLinkActiveOptions]="{exact:true}"><a routerLink="/">Home</a></li>
        <li role="presentation" routerLinkActive="active"><a routerLink="/servers">Servers</a></li>
        <div *ngIf="showUser">
        <li role="presentation" routerLinkActive="active"><a routerLink="/users">Users</a></li>
        </div>
      </ul>
    </div>
  </div>
  <div class="row">
    <div class="col-xs-12 col-sm-10 col-md-8 col-sm-offset-1 col-md-offset-2">
      <router-outlet></router-outlet>
    </div>
  </div>

The code above includes an if condition to control the visibility of a tab:

        <div *ngIf="showUser">
        <li role="presentation" routerLinkActive="active"><a routerLink="/users">Users</a></li>
        </div>

This tab will only be shown if the variable showUser is true. Otherwise, it will not appear in the home page.

Check out the TypeScript file (TS) here:

export class AppComponent{
  showUser : boolean = true;

  ngOnInit() {
    this.showUser = false;
  }
}

In this example, I've manually set this.showUser as false. In a real-world application, this value would typically depend on certain conditions, like:

  ngOnInit() {
    let user = this.localStorage.getItem('user');
    if(user.value == null || user.value == undefined) {
       this.showUser = false;
     }
  }

Therefore, the user menu will only display if the condition is true.

However, there is an issue where changing the URL to include /users leads to a redirection to the users page:

https://routing-angular-bjbjqd.stackblitz.io/users

My goal is to prevent this from happening unless the showUser condition is met.

How can I ensure that the URL does not change unless showUser is true?

Answer №1

To successfully manage this operation, it is essential to regulate access through UserGuard.

Start by defining the showUser variable as a global variable using localStorage

localStorage.setItem('showUser', true|false);

Next, retrieve the data from localStorage in the guard and carefully examine each attempt to access the specified path

@Injectable()
class UserGuard implements CanActivate {
  constructor() {}

  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean|UrlTree>|Promise<boolean|UrlTree>|boolean|UrlTree {
    return localStorage.getItem('showUser');
  }
}

This guideline should facilitate your understanding and implementation process

Answer №2

To fully meet your requirements, relying solely on the Auth guard may not be sufficient. Consider implementing admin guards or User Specific guards in your application.

import { Injectable } from '@angular/core';
import {
    CanActivate, Router,
    ActivatedRouteSnapshot,
    RouterStateSnapshot,
    CanActivateChild,
    NavigationExtras,
    CanLoad, Route
} from '@angular/router';

@Injectable()
export class UserGuard implements CanActivate, CanActivateChild, CanLoad {
    userType: string;
    constructor(private router: Router) { }

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

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

    canLoad(route: Route): boolean {
        let url = `/${route.path}`;
        return this.checkLogin(url);
    }

    checkLogin(url: string): boolean {
        this.userType = sessionStorage.getItem('userType'); // Verify user type here
        if (this.userType === "user") {
            return true;
        }
    }
}

Define routing as follows:

{ path: 'user', component: UserComponent, canActivate: [AuthGuard, UserGuard] }

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

The Date object in Typescript is represented as a string

My typescript interface includes a variable called start, which is typed as Date | null. This data is retrieved from a dotnet API that returns a DateTime object. The issue arises when the start variable is passed through a function in Date-fns, causing a R ...

What criteria does Angular use to determine when the aot compiler should be utilized?

This page discusses the concept of modules in Angular and explains the two approaches to bootstrapping - dynamic and static. The configuration for these approaches is typically found in main.ts: // Using the browser platform with a compiler import { platf ...

Can someone point me to the typescript build option in Visual Studio 2019 Community edition?

When I created a blank node.js web app on VS 2015, there was an option under project properties called "TYPESCRIPT BUILD" that allowed me to configure settings like combining JavaScript output into a single file. After upgrading to VS 2019 Community, I ca ...

What is the best way to store items in localStorage within Angular version 4.4.6?

I have been working on implementing a basic authentication system in Angular 4.4 with MongoDB as the backend database. login.component.ts import { Component, OnInit } from '@angular/core'; import { AuthService } from 'app/services/auth.ser ...

"An error occurred: Uncaught SyntaxError - The import statement can only be used within a module. Including a TypeScript file into a

I need to integrate an Angular 10 TypeScript service into a jQuery file, but I am facing an issue. When I try to import the TypeScript service file into my jQuery file, I encounter the following error: Uncaught SyntaxError: Cannot use import statement outs ...

What is the ideal way to name the attribute labeled as 'name'?

When using the ngModel, the name attribute is required. But how do I choose the right name for this attribute? Usually, I just go with one by default. angular <label>First Name</label> <input type="number" name="one" [( ...

The ActionsSubject from ngrx does not properly finalize when used in a modal dialog box

Within a mat dialog, I am utilizing ActionsSubject to monitor dispatch actions and set the closed flag to true. // Facade sellProduct(data: ProductSellRequestDto): void { this.store.dispatch(MarketActions.sellProductMarketAccount({ data })); } OnSellPro ...

Unfortunately, an exception was encountered: ES Module must be loaded using the import statement

Currently, I am addressing some vulnerability concerns within my Angular development environment. These vulnerabilities are found within internal dependencies, so I have included resolutions in the package.json file. However, when I attempt to run 'ng ...

Utilizing objects as values with `react-hook-form`

About the Issue I'm facing an issue with a component that utilizes an object as its value. My goal is to integrate this component with react-hook-form The challenge arises when react-hook-form considers my object as a nested form control Background ...

Converting and Casting Enums in TypeScript

Is there a way to convert one enum into another when they have the same values? enum Enum1 { Value = 'example' } enum Enum2 { Value = 'example' } const value = Enum1.Value const value2 = value as Enum2 ...

Unable to cache new entry at the specified location (/Users/android/.gradle/7.5.1/checksums/sha1-checksums.bin) due to a java.io.IOException with the message "Bad file descriptor"

I encountered two errors when trying to run my React Native project. Issue 1: Failed to add entry '/Users/saadafridi/.gradle/.tmp/gradle_download14928641310389655157bin' to cache sha1-checksums.bin (/Users/saadafridi/Desktop/mobileapp/android/.g ...

Tips for effectively utilizing react-test-renderer/shallow in a TypeScript environment

Looking to utilize react-test-renderer/shallow for testing my react component. However, when I try to import ShallowRenderer from 'react-test-renderer/shallow'; tsc throws an error stating that 'Module '"/Users/dulin/workspace/react-t ...

What is the process for removing an item from a JSON file using an HTTP DELETE request in a Node.js environment?

Essentially, I have a JSON file containing user and group data and I need to delete a specific group from it. Below is a snippet of the JSON file named authdata.json: [{ "name": "Allan", "role": ["Group Admin", "Super Admin"], "group": ["Cool- ...

I am encountering difficulties while attempting to import Typescript files. Upon compiling them into Javascript, I am faced with errors in the web browser, specifically the issue of "exports is not defined"

When I run TodoAppUI.js:15, I get an error saying "Uncaught ReferenceError: exports is not defined" In all my classes, I use the export keyword. For example: export class mysclass { public constructor(){} } Even though I have the proper syntax for impo ...

Highcharts, put a halt to the dynamic spline graph rendering

Utilizing Angular, I successfully implemented a Dynamical Spline Graph by following the guidelines outlined in the HighCharts documentation. An important feature I would like to incorporate is the ability for the chart to pause rendering upon clicking a d ...

Dynamic Variable Translation in Angular 8 using i18n

Within my app.component.html, there is a recurring element on every page: <h1 i18n="@@titleH1">{{title}}</h1> I created a shared service with setters and getters: ... title = new BehaviorSubject('Initial Title'); setTitle(title: s ...

Does the onAuthStateChanged listener in firebase trigger immediately upon user login or logout?

//initialize auth change listener useEffect(() => { auth.onAuthStateChanged((user) => { if (user) { router.replace('/') } }) setInitializing(false) }, []) //*handled by login button const login = asy ...

Angular2 with Typescript is raising concerns over the absence of specific data types in

I am encountering an issue with the following code snippet: var headers = new Headers(); // headers.append('Content-Type', 'application/json'); headers.append('Content-Type ...

Different Ways to Validate Angular 2 FormGroups

Component: ngOnInit() { this.record = new FormGroup({ movement: new FormControl(''), weight: new FormControl('', [Validators.required, Validators.pattern('^[0-9]*$')]), date: new FormControl('' ...

Passing images to Angular components

Just diving into Angular and tasked with a small project for school. I've got a node backend that sends images via base64 to my angular service... imageService.getUserImagesFromDB(id, (result) => { f ...