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

Is it possible to manipulate a modal within a controller by utilizing a certain attribute in HTML, based on specific conditions (without relying on any bootstrap services), using AngularJS?

Within my application, I have a modal that is triggered by clicking on a button (ng-click) based on certain conditions. Here is the HTML code: <button type="button" class="btn btn-outlined" ng-click="vm.change()" data-modal-target="#add-save-all-alert ...

What are the issues causing trouble for my modules, services, and more in Angular ^17?

As I was going through the themes, I couldn't find a similar question. My issue revolves around Angular's inability to locate modules and services that are created using "ng g". Everything seems to be correctly set up, but errors or warnings keep ...

Issue with MaterialUI value prop not updating after dynamic rendering of components when value state changes

As I dynamically generate Material UI form components, I encounter an issue with updating their values. The value prop is assigned to a useState values object, and when I update this object and the state, the value in the object changes correctly but the M ...

Redirecting to new page after submitting form using Ajax

I'm having some trouble with my HTML form submission using JQuery and AJAX. After successfully submitting the form, I want to display a modal and then redirect to another page based on certain conditions. I've written the logic in my JS file wh ...

Using regular expressions to eliminate text located outside of the tags within a string

Presented is a string consisting of an XML string below: var xmlString = "<str>rvrv</str>rvrv<q1>vrvv</q1>vrvrv<q2>rtvrvr</q2>"; I am seeking assistance on how to eliminate text that lies outside the tags (text no ...

Encountered an execution policy error while trying to run the "yo office" command in the Yeoman office add-in generator

I was eager to use Yeoman to develop an Office add-in with Angular. After successfully installing the necessary tools such as Node.js, Angular, Yeoman, and generator-office in PowerShell, I attempted to run the following code: yo office Unfortunately, I e ...

Transforming JSON arrays into object representations

I have a collection of components structured like this: var names = 1)"lat: 40.6447077, lng: -73.878421, address: 1600 Pennsylvania Avenue, Brooklyn, NY 11239, USA" 2)"lat: 40.609099, lng: -73.931516, address: 2015 E. 35th street, Brooklyn, Ny, Un ...

Executing a function right away when it run is a trait of a React functional component

Having a fully functional React component with useState hooks, and an array containing five text input fields whose values are stored in the state within an array can be quite challenging. The main issue I am facing is that I need to update the inputfields ...

Material UI is failing to apply its styles

I tried customizing the default theme provided by Material UI, but unfortunately, the styles are not applying. Can anyone help me with this issue? In My Header.js file, I faced an issue where the customized style was not being applied as expected. const u ...

Issues with jQuery .click and .html functions not functioning as expected

Does anyone have experience creating a game with jQuery? I can't seem to get the options after the first choice to work. Sorry, I don't have a working example at the moment. --- jQuery --- $(document).ready(function() { $(".console"). ...

Tips for transferring state information from a client to a server component within Nextjs?

Currently, I am working on a project where I need to read and write data from a locally stored .xml file that contains multiple <user> tags. The technology stack includes TypeScript and NextJS. The project is divided into three main components sprea ...

Personalizing the text of an item in a v-select interface

Can the item-text be customized for the v-select component? I am interested in customizing each item within the v-select dropdown, similar to this example: :item-text="item.name - item.description" ...

JQuery Autocomplete Error: Unable to access property 'value' of undefined

I am currently utilizing a jquery autocomplete plugin found here. However, I am encountering an issue when I click on a filtered result, triggering the following error: Uncaught TypeError: Cannot read property 'value' of undefined Upon inspecti ...

Encountering an error code of 500 when executing the createIndex function in Pouch

I'm currently working on setting up a basic index, and I have the following code snippet: currentDB.createIndex({ index: { fields: ['name'] } }).then((result) => { }).catch((error) => { }) However, when I try to r ...

Utilizing Protractor's advanced filtering techniques to pinpoint the desired row

I am trying to filter out the specific row that contains particular text within its cells. This is my existing code: private selectTargetLicense(licenseName: string) { return new Promise((resolve => { element.all(by.tagName('clr-dg-tab ...

Creating an AJAX function to display a popup window for users who are already registered - here's how!

I am currently working on a dropwizard-java project. Whenever users click the subscribe button, it displays a thank you message for subscribing and then checks if the user is already registered. I would like to have a pop-up window immediately show whethe ...

Post Request to Express API does not produce any output

Today, I encountered an issue while trying to create a JWT authentication API in Express. When I send a POST request with Postman, it only returns {}. Below is the code for server.js: const express = require("express"); const mongoose = require("mongoos ...

Converting a TypeScript nested dictionary into a list of strings

I am currently working with a nested dictionary and my goal is to convert it into a list of strings. For example, the initial input looks like this: var group = { '5': { '1': { '1': [1, 2, 3], ...

Managing file sizes on the client side prior to transferring them to the server side

I am looking to implement client-side validation for file size. The current code only handles success, but I also want to address file size limitations. Right now, if a file exceeds 2MB, it results in a 500 (Internal Server Error) behind the scenes. Is th ...

Unable to modify the filename of the uploaded file with multer

I've been attempting to modify the name of the image I'm uploading to the server using multer. However, even after utilizing the multer.diskStorage method as per the documentation, the file continues to be saved with random names. MY CODE: con ...