Why Subject subscribe is not working in Angular 9

Viewed 794

I have a Subject defined in the authentication service. When I want to move user information to another component, subscribe doesn't work and it doesn't work. I tried to use it in different hooks, but again it was useless. I also used BehaviorSubject, but null returns.

Does anyone know what the problem is?

auth.service.ts

import {Injectable} from '@angular/core';
import {HttpClient, HttpErrorResponse, HttpHeaders} from '@angular/common/http';
import {AuthModel} from '../Infrastructure/Models/authModel';
import {RegisterUserDeviceModel} from '../Infrastructure/Models/RegisterUserDeviceModel';
import {ResponseModel} from '../Infrastructure/Models/responseModel';
import {RegisterUserDeviceResponseModel} from '../Infrastructure/Models/registerUserDeviceResponseModel';
import {LoginResponseModel} from '../Infrastructure/Models/LoginResponseModel';
import {RegisterDeviceDataMosel} from '../app.component';
import {BehaviorSubject, Subject, throwError} from 'rxjs';
import {UserDataModel} from '../Infrastructure/Models/UserDataModel';
import {catchError, tap} from 'rxjs/operators';
import {RoleEnum} from '../Infrastructure/Enums/RoleEnum';

@Injectable({
    providedIn: 'root'
})
export class AuthService {
    devicecode: string = (<RegisterDeviceDataMosel> JSON.parse(localStorage.getItem('RegisterDeviceData'))).devicecode;
    user = new Subject<UserDataModel>();

constructor(private _http: HttpClient) {
}

Signin(data: AuthModel) {
    let _headers = new HttpHeaders();
    _headers = _headers.append('Content-Type', 'application/json');
    _headers = _headers.append('Access-Control-Allow-Origin', '*');
    _headers = _headers.append('X-Skip-Interceptor', '');
    _headers = _headers.append('device_code', this.devicecode);
    const _options = {headers: _headers};

    return this._http.post<ResponseModel<LoginResponseModel>>('http://localhost:5000/account/login', data, _options)
        .pipe( catchError(this.handelError) , tap(resData => {
            this.handleAuth(data.username, resData.response.access_token, resData.response.refresh_token
                , resData.response.role, resData.response.expires_in);
        }));
}

AutoLoading(): boolean {
    debugger;
    const userData: {
        username: string,
        access_token: string,
        refresh_token: string,
        role: RoleEnum,
        _tokenexpirationDate: string
    } = JSON.parse(localStorage.getItem('userData'));
    if (!userData) {
        return false;
    }
    const loadUser = new UserDataModel(userData.username, userData.access_token, userData.refresh_token
        , userData.role, new Date(userData._tokenexpirationDate));
    if (loadUser.token) {
        this.user.next(loadUser);
        return true;
    }
}

private handleAuth(username, token, refresh_token, role, expiresin) {
    const expirationDate = new Date(new Date().getTime() + +expiresin * 60000);
    const user = new UserDataModel(username, token, refresh_token
        , role, expirationDate);
    debugger;
    this.user.next(user);
    localStorage.setItem('userData', JSON.stringify(user));
}

private handelError(errorResponse: HttpErrorResponse){
    return throwError(errorResponse);
}
}

component

import {AfterViewChecked, AfterViewInit, Component, OnDestroy, OnInit} from '@angular/core';
import * as momenthijri from 'moment-hijri';
import {AuthService} from '../../auth/auth.service';
import {Subscription} from 'rxjs';



@Component({
  selector: 'app-footer',
  styleUrls: ['./footer.component.scss'],
  templateUrl: './footer.component.html',
  providers: [AuthService]
})
export class FooterComponent implements OnInit , OnDestroy {
  private userSub: Subscription ;
  nowDate = new Date();
  hijri;
  public userName;
  public role;

  constructor(private authService: AuthService) {
  }

  ngOnInit(): void {
    this.hijri = momenthijri(this.nowDate.toString()).format('iYYYY/iM/iD');
    this.userSub = this.authService.user.subscribe( res =>{
      debugger;
      this.userName = res.username ;
      this.role = res.role;
    });
  }

  ngOnDestroy(): void {
    this.userSub.unsubscribe();
  }
}

Thank you all for your help

1 Answers

It happens because Subject doesn't store the data inside and you have to subscribe before providing the data in your subject. Also, you can use BehaviorSubject that stores the data inside, and all the time you subscribe to it you will receive this data, but you have to provide an initial value.

On the other hand, you can simulate BehaviorSubject without initial value by user = new ReplaySubject<UserDataModel>(1) which will store the last data and return it every time you subscribe. Hope, my explanations is clear :)

Related