When the page is refreshed, Angular and JWT roles mysteriously vanish into thin

Currently, I am developing a CRUD application with an authentication component where I'm using JWT roles to manage the navigation between pages. This implementation ensures that once a user logs into the application, they will only see menu links relevant to their assigned role.

AuthenticationService.ts

import {HttpClient} from '@angular/common/http';
import {Injectable} from '@angular/core';
import {JwtHelper} from 'angular2-jwt';

@Injectable()
export class AuthenticationService {

  private host:string="http://localhost:8080";
  private jwtToken:string=null;
  private roles:Array<any>=[];
  private tk:any;

  constructor(private http:HttpClient){

  }
  login(user){
    return this.http.post(this.host+"/login",user, {observe:'response'});
  }

  logout(){
    this.jwtToken=null;
    localStorage.removeItem('token');
  }

  saveToken(jwt:string){
    this.jwtToken=jwt;
    localStorage.setItem('token',jwt);
    let jwtHelper=new JwtHelper();
    this.roles=jwtHelper.decodeToken(this.jwtToken).roles;
  }

  loadToken(){
    return this.jwtToken=localStorage.getItem('token');
  }

  isAdmin(){
    for(let r of this.roles) {
      console.log("********************************"+r);
      if(r.authority=='ADMIN') return true;
    }
    return false;
  }
  isDeveloper(){
    for(let r of this.roles) {
      console.log("********************************"+r);
      if(r.authority=='DEVELOPER') return true;
    }
    return false;
  }
  isCommercial(){
    for(let r of this.roles) {
      console.log("********************************"+r);
      if(r.authority=='COMMERCIAL') return true;
    }
    return false;
  }

  isOnline(){
    this.jwtToken=localStorage.getItem('token');
    if (this.jwtToken != null) return true;
    return false;
  }
  isOffline(){
    this.jwtToken=localStorage.getItem('token');
    if (this.jwtToken == null) return true;
    return false;
  }

}

app.component.html

 <!-- partial -->
  <div [ngClass]="{'container-fluid page-body-wrapper':authenticationService.isOnline()}">
    <!-- partial:partials/_sidebar.html -->
    <nav *ngIf="authenticationService.isOnline()" class="sidebar sidebar-offcanvas" id="sidebar">
      <ul class="nav">
        <li class="nav-item nav-profile">
          <a href="#" class="nav-link">
            <div class="nav-profile-image">
              <img src="assets/images/faces/face1.jpg" alt="profile">
              <span class="login-status online"></span> <!--change to offline or busy as needed-->
            </div>
            <div class="nav-profile-text d-flex flex-column">
              <span class="font-weight-bold mb-2">David Grey. H</span>
              <span class="text-secondary text-small">Project Manager</span>
            </div>
            <i class="mdi mdi-bookmark-check text-success nav-profile-badge"></i>
          </a>
        </li>
        <li class="nav-item">
          <a class="nav-link" routerLink="/tasks">
            <span class="menu-title">Dashboard</span>
            <i class="mdi mdi-home menu-icon"></i>
          </a>
        </li>
        <li *ngIf="authenticationService.isAdmin()" class="nav-item">
          <div class="dropdown">
            <a class="nav-link" data-toggle="collapse" (click)="OnClik3()" data-target="#myNavbar3">
              <span class="menu-title">Admin Area</span>
              <i class="menu-arrow"></i>
              <i class="mdi mdi-worker"></i>
            </a>
            <div class="collapse navbar-collapse" [ngClass]="{'show': buttontoggled3}" id="myNavbar3">
              <ul class="nav flex-column sub-menu">
                <li class="nav-item">
                  <a class="nav-link" data-toggle="dropdown" routerLink="/roles">Roles</a>
                </li>
                <li class="nav-item">
                  <a class="nav-link" data-toggle="dropdown" routerLink="/users">Users</a>
                </li>
                <li class="nav-item">
                  <a class="nav-link" data-toggle="dropdown" href="#">XXX API</a>
                </li>
              </ul>
            </div>
          </div>
        </li>
        <li *ngIf="authenticationService.isAdmin() || authenticationService.isCommercial()" class="nav-item">
        <div class="dropdown">
          <a class="nav-link" data-toggle="collapse" (click)="OnClik1()" data-target="#myNavbar1">
            <span class="menu-title">Network</span>
            <i class="menu-arrow"></i>
            <i class="mdi mdi-google-circles-extended"></i>
          </a>
          <div class="collapse navbar-collapse " [ngClass]="{'show': buttontoggled1}" id="myNavbar1">
            <ul class="nav flex-column sub-menu">
              <li class="nav-item">
                <a class="nav-link" data-toggle="dropdown" routerLink="/companies">Companies</a>
              </li>
              <li class="nav-item">
              <a class="nav-link" data-toggle="dropdown" routerLink="/contacts">Contacts</a>
              </li>
              <li class="nav-item">
                <a class="nav-link" data-toggle="dropdown" href="#">Whatsapp API</a>
              </li>
            </ul>
          </div>
        </div>
        </li>

An issue arises when the user stays logged in but navigates away from the page and returns; the menu items linked to specific user roles disappear. How can I resolve this problem? Your suggestions are highly appreciated.

Answer №1

As mentioned by @user184994, loading the roles can be achieved in the following way:

checkAdminRole(){
    let tokenDecoder=new TokenDecoder();
    this.userRoles=tokenDecoder.decodeToken(this.accessToken).roles;
    for(let role of this.userRoles) {
      console.log("Checking role: "+role);
      if(role.authority=='ADMIN') return true;
    }
    return false;
  }

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

Passing data from the front-end of an Angular component (app.component.html) to the back-end of another component (other.component.ts)

Imagine a scenario involving basic crud operations. Within the app.component.html file, there are multiple input fields and buttons. Upon clicking a button in app.component.html, the value of an HTML field is sent to the 'other.component.ts' comp ...

Pass a React component as a required prop in Typescript when certain props are necessary

I am currently working on a project where I need to create a custom TreeView component using React and Typescript. My goal is to have the ability to inject a template for each TreeNode in order to render them dynamically. My main challenge right now is fi ...

Guide to assigning positions in an array of a particular component with its selector utilizing Angular:

I am a beginner when it comes to Angular and I have a question regarding setting positions of an array that is initially declared as empty in one component, using its selector in another component. Let's take for example a component named "array" whe ...

Having trouble organizing data using matSort in conjunction with API information

Everything was running smoothly with my mat-table until I tried adding mat-sort as per the official API documentation. Unfortunately, it failed at ngAfterViewInit with the following error message: ERROR TypeError: Cannot set property 'sort' of u ...

Can we replace node_module imports with a different module (e.g. swapping lodash with lodash-es)?

Currently in the process of upgrading from angular 9 to angular 10 within my mono-repo. Encountering numerous warnings like the ones below: WARNING in \libs\global-search\src\lib\components\status\status.component.ts depe ...

Issue with Angular and Ionic-v4 ion-select popover malfunctioning

Is there a way to programmatically open ionSelect in popover mode? @ViewChild('selectNotificationList') selectNotificationList: IonSelect; This is the method to open an ion-select: clickNotificationNumber() { this.selectNotificationList.in ...

How can I efficiently create an editForm in Angular?

Within my database, there are numerous users, each with their own collection of recipes. Each recipe contains various properties and a list of ingredients. Take a look at the screenshot below: Recipe with all properties When a user goes to edit a recipe ...

Uploading an image in Typescript on IE11 using Angular 4

I'm having an issue uploading an image to my web application using Angular 4. I convert the input file using readAsBinaryString() and extract the ASCII code using btoa() before passing it to a backend service. While this process works smoothly on Chro ...

Evaluating operational Angular component - Error: $(...).somename function is not defined

I've encountered an issue while attempting to test my component in Angular. The component itself functions correctly during regular use, but when I try to run the tests using "yarn run test", I receive the following error message: HeadlessChrome 0.0. ...

Switching between Angular components with a button press

I'm looking to switch from one Angular component to another when a button is clicked. Specifically, I have two components: app and login. Upon clicking a button in `app.component.html`, I want to navigate to `login.component.html`. Here's what I& ...

What leads to the inability to utilize environment variables in this TypeScript app built with Vue 3?

Currently, I am developing a single page application utilizing Vue 3 and TypeScript. The main purpose of this app is to interact with an API. All the necessary information including the API's URL and key are stored in the 'src\env.js' f ...

Tips for utilizing automatic type detection in TypeScript when employing the '==' operator

When using '==' to compare a string and number for equality, const a = '1234'; const b = 1234; // The condition will always return 'false' due to the mismatched types of 'string' and 'number'. const c = a = ...

Classes in Typescript can implement interfaces to streamline the functionality

Recently, I've been working on creating my custom class called AxiosError and I can't help but feel like the code is a bit repetitive. //types.ts export interface IAxiosRequest{} export interface IAxiosResponse{} export interface IAxios ...

What causes the website to malfunction when I refresh the page?

I utilized a Fuse template to construct my angular project. However, upon reloading the page, I encountered broken website elements. The error message displayed is as follows: Server Error 404 - File or directory not found. The resource you are looking fo ...

The forkJoin method fails to execute the log lines

I've come up with a solution. private retrieveData() { console.log('Start'); const sub1 = this.http['url1'].get(); const sub2 = this.http['url2'].get(); const sub3 = this.http['url3'].get(); ...

Having trouble with Apache Echarts? The error message "Legend data should be the same as series name or data name" is causing

Having an issue with Apache Echarts. I'm getting the error message "Legend data should be same with series name or data name" even though my series name and legend data names match. The chart is not printing correctly. Can anyone identify where I am g ...

TypeScript function object argument must be typed appropriately

In the code, there is a function that I am working with: setTouched({ ...touched, [name]: true }); . This function accepts an object as a parameter. The 'name' property within this object is dynamic and can be anything like 'email', &ap ...

Using Pydantic to define models with both fixed and additional fields based on a Dict[str, OtherModel], mirroring the TypeScript [key: string] approach

Referencing a similar question, the objective is to construct a TypeScript interface that resembles the following: interface ExpandedModel { fixed: number; [key: string]: OtherModel; } However, it is necessary to validate the OtherModel, so using the ...

Angular 2 Shows No Mercy: AOT Promise Rejection Unhandled

I've built a small Angular 2 application that retrieves data from an ASP.net MVC Web API while utilizing Authentication. I'm attempting to employ Ahead Of Time compiler in Angular 2 and have executed the following command: node_modules \ ...

Tips on invoking Bootstrap's collapse function without using JQuery

We are facing a challenge with our TypeScript files as we have no access to jQuery from them. Our goal is to trigger Bootstrap's collapse method... $(object).collapse(method) but without relying on jQuery. Intended Outcome //Replicates the functio ...