Home > Software design >  BehaviorSubject tells me next is undefined
BehaviorSubject tells me next is undefined

Time:08-02

In my auth.service.ts file

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { JwtHelperService } from "@auth0/angular-jwt";
import { BehaviorSubject, map, Observable } from 'rxjs';
import { environment } from 'src/environments/environment';
import { Role } from '../modal/Role.enum';
import { User } from '../modal/User';

  constructor(private httpClient: HttpClient) {
    let localUser = localStorage.getItem('user');
    if (localUser) {
      this.userSubject = new BehaviorSubject<User>(JSON.parse(localUser));
      this.user = this.userSubject.asObservable();
    }
  }


  public get userValue(): User {
    return this.userSubject?.value;
  }


Login(model: any) {
    return this.httpClient.post(this.url   'Login', model)
      .pipe(
        map((response: any) => {
          const tokenInfo = response;
          if (tokenInfo && tokenInfo?.data?.token) {
            localStorage.setItem('token', tokenInfo.data.token);
            this.decodedToken = this.JwtHelper.decodeToken(tokenInfo.data.token);
            this.isLogin.next(true);
            this.customerStatus().subscribe((it: any) => {
              let data = it.data;
              const role: Role = (<any>Role)[data.roleCode];
              let user: User = {
                id: data.id,
                firstName: data.firstName,
                lastName: data.lastName,
                email: data.email,
                phoneNumber: data.phoneNumber,
                networkID: data.networkID,
                token: tokenInfo.data.token,
                role: role
              }
              localStorage.setItem('user', JSON.stringify(user));
              setTimeout(() => {
                console.log("User")
                console.log(user)
                this.userSubject.next(user); // is undefined here
              }, 1500);
            });
          }
          return response;
        })
      );
  }

In my Login method, this.userSubject.next(user) is undefined here

If I inspect the value for user, it has a valid JSON data.

Pressing Refresh on the browser causes the application to work as expected. But I dont want to tell people to press 'Refresh'

I added the timeout because I thought the userSubject needed a little more time to catch up. It does not seem to be the case.

I am using Angular 14

CodePudding user response:

I believe what's happening here is the logic for initiating is incorrect

let localUser = localStorage.getItem('user');
if (localUser) {
  this.userSubject = new BehaviorSubject<User>(
     JSON.parse(localUser) || { foo: 'hello' }
  );
}

This means that if user don't have that in local storage, your subject isn't defined at all.

I think you are better initialising this at first maybe even outside constructor. And then passing the value in it, or just adding an else in that condition, to make sure it's always initialised.

userSubject = new BehaviorSubject<User>(null);

constructor() {
   this.userSubject.next(...)
}

I would also recommend here using ngOnInit, instead of constructor

  • Related