Learn the steps to dynamically show a navbar component upon logging in without the need to refresh the page using Angular 12

After logging in successfully, I want to display a navbar on my landing page. Currently, the navbar only shows up if I reload the entire page after logging in. There must be a better way to achieve this without a full page reload.


app.component.html

<app-navbar></app-navbar>
<router-outlet></router-outlet>

login.component.ts

login(){
    this.credentials = this.myForm.value;
    if(this.credentials){
      this.loginService.authenticate(this.credentials)
      .subscribe(data => {
        this.storageService.setLocalStorageItem('auth', JSON.stringify(data));
        this.dataService.global.showNav = true;
        this.sharedService.getProjectMetadata()
        .subscribe(metadata => {
          this.storageService.setLocalStorageItem('projectMetaData', JSON.stringify(metadata));
          this.router.navigate(['/home']);
        })
      }, err => console.log(err));
    } else {
      console.log('Please enter your username and password');
    }
  }

data.service.ts

import { Injectable } from '@angular/core';
import { Subject, Subscription } from 'rxjs';
import { filter, map } from 'rxjs/operators';
import { IGlobal, IMessage } from '../../Shared/interfaces';
import { MessageCallback } from '../../Shared/types';

@Injectable({
  providedIn: 'root'
})
export class DataService {
  constructor() { }

  date: string = (new Date()).toString();

  global: IGlobal = {
    showNav: false,
    sessionTimedOut: false,
    timezone: this.date.substring(this.date.indexOf('GMT')),
    projectMetaData: {
      name: ''
    },
    isAdmin: false,
    auth: {
        roles: {
            admin: false,
            developer: false
        }
    }
  }

  private handler: Subject<IMessage> = new Subject<IMessage>();

  broadcast(type: string, payload: any){
    this.handler.next({type, payload});
  }

  subscribe(type: string, callback: MessageCallback): Subscription {
    return this.handler.pipe(filter(message => message.type === type), map(message => message.payload))
                        .subscribe(callback);
  }
}

navbar.component.html

<mat-toolbar fxLayout="row" color="primary" *ngIf='showNavbar'></mat-toolbar>

navbar.component.ts

export class NavbarComponent implements OnInit {
  user: IAuth = {};
  showNavbar: boolean;
  progressbar: number = 0;

  constructor(
    private storageService: StorageService,
    private dataService: DataService
  ) { 
    this.showNavbar = this.dataService.global.showNav;
  }

  ngOnInit(): void {
    this.user = JSON.parse(this.storageService.getLocalStorageItem('auth'));
    if(this.user){
      this.showNavbar = true;
    }
  }

}

Please provide suggestions or solutions. Your assistance is highly valued. Thank you.

Answer №1

The issue at hand is as follows:

  • After a successful authentication in the login() function, there is no communication with the navbar.component.ts
  • The showNavbar variable in navbar.component.ts controls the display/hide functionality of the navbar template.
  • Although dataService.global.showNav is set to true, it does not trigger a change detection in the navbar components because it is only copied to 'showNavbar' during initialization.
  • Therefore, the navbar is loaded before logging in, possibly with the showNavbar evaluated as false, and it is not re-evaluated until the page is reloaded.
  • On page reload, the value is read from localStorage which provides the latest value for showNavbar.

I propose two solutions{S1,S2} to resolve this issue.

Solution 1:

1. Emit a message via subject from the login component indicating a successful login status
2. Subscribe to this status in the navbar component and based on the subscription, control the rendering of the navbar template
3. It seems like the `broadcast` and `subscribe` functions in dataservice handle this using an IMessage type subject.
4. Refer to the sample code below and adjust it according to your application needs.
For example: login.component.ts

this.dataService.broadcast('authSuccess',{auth:'successful'})

In navbar.component.ts

OnInit() {
   this.dataService.subscribe('authSuccess',setShowNavbar);
}
setShowNavbar() {
  this.showNavbar=true;
}

Solution 2:

This method may not be the most elegant or easy to track, but it serves as a quick fix solution.

navbar.component.html

<mat-toolbar fxLayout="row" color="primary" *ngIf="dataService.global.showNav"></mat-toolbar>

Using this approach will trigger a change detection whenever the value in dataService.global.showNav is updated, consequently evaluating ngIf accordingly. Note: When seeking help on public forums, it's advisable to provide a small working prototype on platforms like stackblitz/jsfiddle/codesandbox. This makes it easier for others to pinpoint the exact problem and offer specific solutions promptly.

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

Unable to locate module: '@material-ui/pickers' - Material UI React

I encountered an error that said: Material UI React - Module not found: Can't resolve '@material-ui/pickers' in React. Previously, I faced a similar issue with '@date-io/date-fns' but was able to fix it by updating to the latest ...

Important notice: It is not possible to assign refs to function components. Any attempt to do so will result in failure. If you intended to assign a ref, consider

My console is showing a warning when I use the nextJs Link component. Can someone assist me in resolving this issue and providing an explanation? Here is the message from the console: https://i.stack.imgur.com/jY4FA.png Below is a snippet of my code: im ...

Comparing JS Async/Await, Promise, and Callbacks: Which is Best

I'm trying to wrap my head around the differences between callbacks, promises, and async/await. While I understand how callbacks and promises work, I'm struggling with grasping the usage of async/await. I know it's essentially a syntactic su ...

Angularjs still facing the routing issue with the hashtag symbol '#' in the URL

I have recently made changes to my index.html file and updated $locationProvider in my app.js. After clicking on the button, I noticed that it correctly routes me to localhost:20498/register. However, when manually entering this URL, I still encounter a 4 ...

Interference with ElementClickInterceptedException in Selenium is caused by the presence of a WebPack iframe within an Angular application, despite implementing WebDriverWait

Everything was going smoothly with my automation code until suddenly, an ElementClickIntercepted exception started occurring when trying to click the "Sign In" button on the login screen: public class LoginPage { private readonly IWebDriver driver; ...

Update: "Mui V5 - Eliminate collapse/expand icons in TreeView and reduce TreeItem indentation"

My current project involves Mui V5 and I am looking to customize the TreeView component. Specifically, I need to remove the collapse/expand icons as I want them to be integrated into the TreeItem label component on the left side instead of the right. Add ...

Fetching locales asynchronously in nuxt.js using i18n and axios: A step-by-step guide

I am facing an issue with getting the location asynchronously. Whenever I try to implement my code, it results in a "Maximum call stack size exceeded" error. How can I resolve this issue? Previously, I attempted to retrieve the location by using the axios ...

Using the function goToPage() within the TabbedHeaderPager component

I am currently working on a project that involves using TabbedHeaderPager, and I need to change tabs programmatically. I have been attempting to use the function goToPage() but have run into difficulties accessing it. I have tried passing it as a prop an ...

Navigating Paths in Real-time with Javascript - Node.js

When working with PHP, dynamic routing can be achieved by defining classes and methods like: class Route { public function homePage () { echo 'You are on the home page' } public function otherPage () { echo 'You are on so ...

The Chrome browser is experiencing delays with processing ajax requests, causing them

When I make a series of 8 requests in quick succession, they load successfully. However, any requests made after that get stuck in a "pending" state. Below is my basic HTML template: <!DOCTYPE html> <html> <head> <meta charset= ...

Issue: Unable to link with 'dataSource' as it is not a recognized feature of 'mat-tree'

Upon following the example provided at https://material.angular.io/components/tree/overview, I encountered an error when trying to implement it as described. The specific error message is: Can't bind to 'dataSource' since it isn't a kn ...

The mermaidAPI.initialize function in Angular does not support the maxTextSize option

I'm currently encountering an issue while attempting to utilize mermaidAPI.initialize in an Angular environment. ngOnInit(): void { this.windowHeight = window.innerHeight; mermaidAPI.initialize({ maxTextSize: 1000000, logLevel: & ...

Retrieve the color of the TripsLayer in deck.gl

layers.push(new TripsLayer({ id: 'trips', data: trips, getPath: (d: Trip) => d.segments.map((p: Waypoint) => p.coordinates), getTimestamps: (d: Trip) => d.segments.map((p: Waypoint) => p.timestamp), ...

When attempting to bind various data to a single div using knockout js, the issue of duplicate records appearing arises

I am encountering an issue with a div that is set up to display 10 records at a time. When the user clicks on the next link, the next set of 10 records should be loaded from the server. However, after binding the newly added records, they are being shown m ...

The retrieval process is unable to receive a response from the server

Question: I am encountering an issue with the fetch API in the client-side code. Here is the snippet of the code: window.fetch('/signup', { method: 'post', headers: { 'Content-Type': 'application/x-www-form-urlen ...

When switching tabs, Ion-select should not reload the selected name

Whenever I switch tabs and then return to the previous tab in Ionic, the select field that was previously set becomes null, even though the page is still loading and the variable is populated. <ion-header color="primary"> <ion-navbar> &l ...

The synergy between ES6 arrow functions and array mapping techniques

I'm currently exploring shorthand methods of writing ES6 code and I've come across an example that has left me puzzled. The last shorthand used, "({length})", retrieves the length property of an array. While I understand how it works in this cont ...

I created a custom discord.js-commando command to announce all the channels that my bot is currently active in, however, encountered an unexpected error

const Commando = require('discord.js-commando'); module.exports = class AnnounceCommand extends Commando.Command { constructor(client) { super(client, { name: 'announce', aliases: ['an'], ...

What are the distinctions between utilizing util.inherits() and prototypes for inheritance in node.js?

The method util.inherits() allows for the inheritance of methods from one function to another. Prototypes are also a way to achieve inheritance in JavaScript. I am wondering when it is best to use .inherits() versus changing the prototype chain. Any advi ...

I find it confusing how certain styles are applied, while others are not

Working on my portfolio website and almost done, but running into issues with Tailwind CSS. Applied styling works mostly, but some disappear at certain breakpoints without explanation. It's mainly affecting overflow effects, hover states, and list sty ...