Search code examples
angularangular2-routingangular-servicesangular-route-guards

Angular service variable updated value not reflected in component


I am facing issues while accessing the service variable values inside my angular component. Navbar component is setting user as logged in inside the service and routing guard is responsible for enabling children route, but routing guard is not able to fetch the updated value of userStatus

import { Component, OnInit } from '@angular/core';
import { UserDetailsService } from '../user-details.service.js';
import { Router } from '@angular/router';

@Component({
  selector: 'app-navbar',
  templateUrl: './navbar.component.html',
  styleUrls: ['./navbar.component.css']
})
export class NavbarComponent implements OnInit {
  UserStatus: boolean;

  constructor( private UserService: UserDetailsService, private router: Router) { }

  ngOnInit() {
    this.UserService.UserStatus.subscribe((data: boolean) => {
      this.UserStatus = data;
    });
    this.UserService.getUserStatus();
  }
  logout() {
    this.UserService.UpdateStatus(false);
    this.router.navigate(['login']);
  }
  login() {
    this.UserService.UpdateStatus(true);
    this.router.navigate(['home/products']);
  }
}

Routing Guard Component

import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router, CanActivateChild} from '@angular/router';
import { Observable } from 'rxjs';
import { UserDetailsService } from './user-details.service.js';

@Injectable({
  providedIn: 'root'
})
export class LoginGuardGuard implements CanActivateChild, CanActivate {
  constructor(private userDetails: UserDetailsService, private router: Router) {}
  canActivateChild(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
      if (this.userDetails.getUserStatus()) {
        return true;
      } else {
        this.router.navigate(['login']);
        // return false;
      }
  }
  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
      if (this.userDetails.getUserStatus()) {
        return true;
      } else {
        this.router.navigate(['login']);
        return false;
      }
  }
}

Solution

  • This is happening because in your app-navbar and route-guard component, you have imported your service with a js extension which is against the singleton model of services inside angular.

    Because of the .js extension, the transpiler is identifying them as two separate instances.

    So changing the imports from

    import { UserDetailsService } from '../user-details.service.js';
    

    to

    import { UserDetailsService } from '../user-details.service';
    

    should fix the issue.