Refreshing Angular 9 component elements when data is updated

Currently, I am working with Angular 9 and facing an issue where the data of a menu item does not dynamically change when a user logs in. The problem arises because the menu loads along with the home page initially, causing the changes in data to not be reflected in the menu items until I manually refresh the page. Despite my efforts using Renderer2, ChangeDetectorRef, and ElementRef, I have been unable to reload the menu automatically. Below are the relevant elements as the actual component code is lengthy. Feel free to ask if you require any additional information:

Html:

              <div class="widget-text">
                  <a mat-button [matMenuTriggerFor]="accountMenu" #accountMenuTrigger="matMenuTrigger" *ngIf="!isLoggedIn">
                    <mat-icon>person</mat-icon>
                    <span fxShow="false" fxShow.gt-sm class="flag-menu-title">Account</span>
                    <mat-icon class="mat-icon-sm caret cur-icon">arrow_drop_down</mat-icon>
                </a>
                <mat-menu #accountMenu="matMenu" [overlapTrigger]="false" xPosition="before" class="app-dropdown">
                    <span>
                        <button mat-menu-item [routerLink]="['/admin/login']" routerLinkActive="router-link-active">
                          <mat-icon >person</mat-icon>
                          <span>Login</span>
                        </button>
                        <button mat-menu-item [routerLink]="['/admin/login']" routerLinkActive="router-link-active">
                          <mat-icon>person_add</mat-icon>
                          <span>Register</span>
                        </button>
                    </span>
                </mat-menu>
                <a mat-button [matMenuTriggerFor]="profileMenu" #profileMenuTrigger="matMenuTrigger" *ngIf="isLoggedIn">
                  <mat-icon>person</mat-icon>
                  <span fxShow="false" fxShow.gt-sm class="flag-menu-title">Howdy, {{name}}</span>
                  <mat-icon class="mat-icon-sm caret cur-icon">arrow_drop_down</mat-icon>
              </a>
              <mat-menu #profileMenu="matMenu" [overlapTrigger]="false" xPosition="before" class="app-dropdown">
                  <span>
                      <button mat-menu-item [routerLink]="['/admin/profile']" routerLinkActive="router-link-active">
                        <mat-icon >person</mat-icon>
                        <span>Profile</span>
                      </button>
                      <button mat-menu-item (click)="logout()">
                        <mat-icon>warning</mat-icon>
                        <span>Logout</span>
                      </button>
                  </span>
              </mat-menu>
                  </div>

typescript:

public name;
public isLoggedIn = false;

  constructor(public router: Router, private cartService: CartService, public sidenavMenuService:SidebarMenuService) {
    this.checkLogin();
    this.name = Cookie.get('userName');
  }

public checkLogin(): any {
    if(Cookie.get('authtoken')) {
      this.isLoggedIn = true;
    }
  }

Answer №1

Keep it simple when dealing with authentication by using a logged in guard (auth guard) once you've logged in.

import { Injectable } from '@angular/core';
import { Router, CanActivate } from '@angular/router';
import { AuthService } from './auth.service';
@Injectable()
export class AuthGuardService implements CanActivate {
  
  constructor(public auth: AuthService, public router: Router , private sideMenuService: SideMenuService) {}
  
  canActivate(): boolean {
    if (!this.auth.isAuthenticated()) {
      this.sideMenuService.sideMenuData.next({...data});  // Dispatch the side menu service data here
      this.router.navigate(['dashboard']); // Redirect to dashboard page after authentication
      return false;
     }
   return true;
   } 
 }
  
} 

After redirecting to the Dashboard Page, inject the sideMenu Service and subscribe to the Behavior Subject menu data field in the Dashboard component.

public name;
public isLoggedIn = false; // No need to check login here, as you are redirected from auth guard
  constructor(public router: Router, private cartService: CartService, 
   public sidenavMenuService: SidebarMenuService) {
   this.checkLogin();  // Authentication handled by auth guard

   this.name = Cookie.get('userName');
}

public ngOnInit(){
  this.sideMenuService.sideMenuData.subscribe((data)=>{
    // Receive dynamic data here and assign to any component field
 });
}
 public checkLogin(): any {
    if(Cookie.get('authtoken')) {
    this.isLoggedIn = true;
 }

}

This method ensures that each time you log in, dynamic data is dispatched and updated in the Behavior Subject for components like the Dashboard component to access.

Hope this explanation proves helpful.

Answer №2

Upon the creation of the page, the constructor is only executed once.

constructor(public router: Router, private cartService: CartService, public sidenavMenuService:SidebarMenuService) {
    this.checkLogin();
    this.name = Cookie.get('userName');
  }

Based on the code provided, if the cookie authtoken is not found during construction, it becomes impossible for your app to determine if it was created by another (login) process.

It is advisable to call the checkLogin function and assign the name immediately after completing the login process.

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

FusionCharts Gauges may share similar code, but each one produces a unique output

Currently, I am developing a project that involves creating a dashboard with 3 gauges. These gauges are enclosed in bootstrap cards with a column value set to 4. In the layout of the dashboard, these 3 cards are positioned next to each other. I have succe ...

What methods can I use to emphasize three distinct dates?

I'm facing difficulty highlighting three specific dates: "10-11-2020", "22-11-2020", and "07-11-2020" using React.js and Datepicker. Unfortunately, my attempts have not been successful so far. Here is the code snippet I am working with: import React, ...

Creating a function within a module that takes in a relative file path in NodeJs

Currently, I am working on creating a function similar to NodeJS require. With this function, you can call require("./your-file") and the file ./your-file will be understood as a sibling of the calling module, eliminating the need to specify the full path. ...

The $.parseJSON function accurately retrieves valid items but also presents an endless stream of undefined

Currently, I am in the process of developing a Flask application that fetches teams from a football league. The teams_list method returns the result of an AJAX request. While the output is correct, it seems to trigger an infinite loop that significantly sl ...

Reload iframe content using a .php file within a different iframe

I am currently working on a page that consists of 7 different iframes: <iframe id="leftframe" src="structure/leftbar.php"></iframe> <iframe id="headerframe" src="structure/header.php"></iframe> <iframe id="menuframe" src="struct ...

Explore by the anchor tag

I've recently implemented a search bar utilizing Bootstrap. This is the code for the search bar: <div class="md-form mt-0"> <input class="form-control" id="myInput" type="text" placeholder="Sear ...

Tips for connecting Angular events to <input> elements in HTML?

Within my Angular application, the value of a variable is manipulated by an HTML element <input> through two-way binding like this: <input [(ngModel)]=variableName (OnKeyup)="DoSomething" > However, the two-way binding with ...

What is the best way to specify a type for an object that may or may not contain a certain property?

I encountered a runtime TypeError that I believe should have been caught during compile time with TypeScript. Here is the code snippet: type MyData = Record<string, Record<string, string>>; function retrieveData(): MyData { return { ...

"Utilize Angular's $http module to execute a POST request for

Hey everyone, I'm a beginner with AngularJS and I've run into a problem while working on my project. I encountered this error: ReferenceError: $http is not defined when attempting to utilize the following code: 'use strict'; ...

Acquiring information from file within component operation

When a user drags and drops a file, how can I retrieve it from the drop event? HTML file <div (drop)="drop($event)" > drop file here </div> TS file drop (event) { console.log(event.target.files.length); // I need to retrieve the file her ...

How can images be resized according to screen resolution without relying on javascript?

Looking to use a large banner image on my website with dimensions of 976X450. How can I make sure that the image stretches to fit higher resolution monitors without using multiple images for different resolutions? ...

Can I use leaflet to customize the types of roads displayed on the map?

Is there a way to customize the types of roads displayed at different zoom levels using data from the OSM highways list? I have checked the Leaflet documentation but couldn't find the answer. If you happen to come across it, please share the link. e ...

Dynamic RSS Aggregator

I'm interested in developing a simple application that can retrieve RSS feeds from any feed URL. Can anyone provide me with some basic guidance on how to accomplish this? I'm fairly new to AJAX and similar technologies, so any assistance would b ...

Plaid webhook failing to activate

I've been struggling to set up Plaid transaction webhooks in an api, as I can't seem to get any webhooks to trigger. I followed the plaid quickstart code and included the webhook parameter: Plaid.create({ apiVersion: "v2", clientName: ...

What is the best way to design a dynamic menu using HTML, CSS, and jQuery, where each li element gradually disappears?

Consider this menu structure: <ul class="main-menu"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> </ul> My task is to dynamically hide th ...

Comparison of getComputedStyle() and cssText functionality between Internet Explorer and Firefox

Take a look at this example to see the issue in action. I'm attempting to access the cssText property of a <div> using window.getComputedStyle(element) (which provides a CSSStyleDeclaration object). While this works smoothly in Chrome, it' ...

Retrieving a dynamic JSON object for the MusicBrainz application using AngularJS

I want to incorporate a search form into my application that sends the form result to the specified link. I am retrieving artist names from the musicbrainz JSON database using the following request: "NAME OF AN ARTIST"%20e*&fmt=json The "NAME OF AN AR ...

Generate a new data type based on the value of a single attribute within a collection of objects

Is there a way to extract a specific property of a combined type and generate a new type from it? Consider the following example: type Actions = | { type: "ADD_COLUMN"; newColumnIndex: number; column: SelectorColumnData; } | { type: ...

Configuring Stylelint in a NextJS project using Emotionjs

I recently encountered an issue while trying to integrate Stylelint into a new NextJS Typescript project with EmotionJS. Many rules were not working in my styles files, and the only error I could identify was Unknown word CssSyntaxError. This particular U ...

Cleaning out input fields in React applications

When I click on the <button type="submit" className="btn btn-primary">Create</button>, a card with hero is generated. Then, using .then(() => clearFields()), I am able to clear the input fields so that clicking the Create ...