Issue with Observables in Angular 2 when trying to implement login functionality

Hey there, I'm currently facing an issue with displaying the logged-in user's username in the navbar. The username is not updating immediately after logging in or out. To resolve this issue, I decided to use rxjs's Subject and Observable. Surprisingly, it works perfectly when I log out, but not when I log back in. As a newbie to Angular, I'm not sure what could be causing this problem. Can anyone provide some insights?

navbar.component.ts

  constructor(
    private authService: AuthService,
    private router: Router,
    private flashMessage: FlashMessagesService,
    private toastrService: ToastrService
  ) {
    this.auth = authService;
    authService.isLoggedIn().subscribe(
      status => {
        if(status == false) {
          this.user = null;
        } else {
          this.authService.getProfile().subscribe(profile => {
            this.user = profile.user;
          })
        }
      }
    )
  }

auth.service.ts

  private logger = new Subject<boolean>();

  isLoggedIn(): Observable<boolean> {
    return this.logger.asObservable();
  }

  setLoginLogger(status){
    this.logger.next(status)
  }

  logout(){
    this.authToken = null;
    this.user = null;
    localStorage.clear();
    this.logger.next(false);
  }

  authenticateUser(user){
    let headers = new Headers();
    headers.append('Content-Type', 'application/json');
    return this.http.post('http://localhost:3000/users/authenticate', user, {headers: headers})
          .map(res => res.json());
  }

  storeUserData(token, user){
    localStorage.setItem('id_token', token);
    localStorage.setItem('user', JSON.stringify(user));
    this.authToken = token;
    this.user = user;
  }

login.component.ts

 onLoginSubmit(){
    const user = {
      username: this.username,
      password: this.password
    }

    this.authService.authenticateUser(user).subscribe((data) => {
      if(data.success){
        this.authService.storeUserData(data.token, data.user);

        if(localStorage.getItem('id_token')){
          this.authService.setLoginLogger(true);
          this.router.navigate(['']);
          this.toastrService.success('Hello world!', 'Toastr fun!');
        }

      } else {
        this.toastrService.success('Hello world!', 'Toastr fun!');

        this.router.navigate(['login']);
      }
    })
  }

Answer №1

To ensure that changes are reflected in the navbar.component.ts, you will need to utilize the ChangeDetectorRef.

import { Component, ChangeDetectorRef} from '@angular/core';

constructor(
private authService: AuthService,
private router: Router,
private flashMessage: FlashMessagesService,
private toastrService: ToastrService,private changeDetectorRef: ChangeDetectorRef) {
this.auth = authService;
authService.isLoggedIn().subscribe(
  status => {
    if(status == false) {
      this.user = null;
    } else {
      this.authService.getProfile().subscribe(profile => {
        this.user = profile.user;
        //reflect the changes
         this.changeDetectorRef.detach();
         setInterval(() => {
          this.changeDetectorRef.detectChanges();
         }, 1000);
      })
    }
  }
)
 }

This solution should address your needs. Best wishes!

Answer №2

After some investigation, I discovered the root of the issue. It turns out that the providers were redundant within my components since they were already included in my app.module.ts.

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

Encountering an Issue with Passing Props through Gatsby Link to Access a Prop on the

I am encountering an issue when trying to pass a value to another page for conditional rendering. The bug I'm facing is related to 'location' being undefined during the build process. Despite my efforts, I have been unable to resolve this is ...

The mat table is not displaying the values from the API despite receiving the correct array

I recently made the decision to dive into learning Angular, but I've encountered some difficulties. Specifically, I'm struggling to populate a table with values retrieved from an API using MatTable. Despite receiving the correct values from the A ...

Tips for fixing the issue: How to handle the notification that an error event has already been emitted on the socket?

I'm currently developing my first Angular app by following the instructions provided at this link. However, upon running the app, I encountered the following errors: (node:4064) Warning: An error event has already been emitted on the socket. Please ...

The custom class-validator decorator in NestJS fails to retrieve the value from the parameter

In my Nestjs project, I have created a Custom ValidatorConstraint using class-validator. The purpose is to create my own decorator and apply it later on DTO classes for validations. Let's consider this route: foo/:client After a request is made, I w ...

Include a fixed webpage on JHipster

I need to integrate a static HTML page into my JHipster app. The content of the page will remain static (a privacy policy), but I want it to have the same navbar as other pages for consistency in appearance and seamless navigation. I attempted to create a ...

What methods are available to maximize the capabilities of Node's stream?

I've been attempting to develop a method for Readable Stream, but I quickly reached a point where I couldn't proceed any further. import * as stream from 'stream' //results in: Property 'asdasas' does not exist on type ' ...

Error encountered in Angular 9: nativeElement.selectpicker is not a function while using bootstrap select

I am currently working on implementing a searchable select box with Bootstrap in my Angular 9 project. To achieve this, I have decided to use Bootstrap Select. Below is the code snippet showcasing how I have integrated it into my project: Within my templ ...

What is the proper way to add an SSL cert to an Angular HTTP API request?

Is there a need to utilize a certificate when making an API call to retrieve an access token? For example, if the method is POST at getAccess.com/getCode, how should we handle this in Postman with a certificate attached? I am currently working on an Angula ...

Is there a way to view the console in a released apk?

Currently working with Ionic and in need of exporting a release APK to be able to monitor the console for any potential issues. I am aware that using 'ionic cordova run --device' allows me to view the console, but it only shows a debug APK. Is t ...

Angular: how to manually trigger change detection without using Angular's dependency injection system

Is there a way to globally initiate angular change detection without having to inject something like ApplicationRef? I am looking to utilize the functionality as a standard JavaScript function rather than a service method, in order to avoid the need for ...

What are the steps to create observable data from asynchronous sources?

Recent adopter of observables. I am utilizing ssh2 to retrieve a directory listing from my server. However, I am struggling to convert the data into an observable format since most online examples involve using http instead of an external module. Any sugg ...

Deleting a page reference from the page history stack in Angular 4

I am working on my angular web application and I am looking for a way to remove a specific page reference from the angular page history stack. For example, if I navigate from the login page to the dashboard page, I want to remove the login page reference f ...

Ways to generate an Angular 7 component

Seeking guidance on creating an angular 7 component. I have forked a jsFiddle at this link: https://jsfiddle.net/gauravshrestha/fdxsywLv/. The chart in the fiddle allows data points to be dragged up and down. My goal is to convert this into a component whe ...

Tips for retrieving a variable from a service in Angular

In my create-movies component, I can easily create a movie using a form. @Component({ selector: 'app-createMovie', templateUrl: './createMovie.component.html', styleUrls: ['./createMovie.component.css'] }) export class ...

Tips for transforming a JSON Array of Objects into an Observable Array within an Angular framework

I'm working with Angular and calling a REST API that returns data in JSON Array of Objects like the example shown in this image: https://i.stack.imgur.com/Rz19k.png However, I'm having trouble converting it to my model class array. Can you provi ...

"GraphQL DefinitelyTyped: The go-to resource for TypeScript typings

I have been working on obtaining type definitions for graphql in my project. After installing both graphql and @types/graphql, I am using import * as graphql from "graphql" in my file. Despite this, I am encountering difficulties accessing certain types ...

production environment causing issues with Angular routing

Hey everyone, I need some help with an issue I'm facing. I have an angular project that runs perfectly fine when I use ng serve. However, after building it, I am unable to access the routing paths by directly entering the URL like this: http://localho ...

Using an alias to call a function defined in a separate module in TypeScript

The following code snippet is from the v4.js file located inside the uuid folder within Angular's node_modules: var rng = require('./lib/rng'); var bytesToUuid = require('./lib/bytesToUuid'); function v4(options, buf, offset) { ...

Encountering a hiccup while attempting to initialize a fresh Angular project with the command "ng new my

I encountered an error issue after running the command npm new project0 npm ERR! path D:\Polytech\Génie Informatique\2- Génie Informatique 4\Programmation Web\Angular\project0\node_modules\js-yaml\bin\js ...

Angular 2: Creating child routes within a nested routing module

After browsing through a post related to my issue, I found some guidance on routing to a module as a child of another module in Angular 2 RC 5. However, I must admit that I got a bit confused. The post can be found here: How to route to a Module as a child ...