1
votes

I am developing a Ionic 5/angular aplication, and I am having trouble with the logout feature.

After log out, login page is display but inputs to enter user id and password cant be used (wont take any input from keyboard)

Only clue is following error that some times is displayed.

enter image description here

The logout method in component is :

     login(form){

    this.authService.login(form.value);
    
    this.authService.currentUser.subscribe(
      (data)=>{
        console.log(data);
        if(data) {this.router.navigateByUrl('home')}
          else {
            
            this.router.navigateByUrl('/login')
          }
      },
      (error) => {throw Error(error)}
    );
    
  }

I am using a behaviorSubject to keep track of logged user in service:

 private _currentUser: BehaviorSubject<UserLogueado> = new BehaviorSubject(null);

  currentUser = this._currentUser.asObservable();

  constructor(private hashingService: HashingService, private router: Router, private http: HttpClient) { }

  encriptarContrasenia(contrasenia: string): string {
    
    return this.hashingService.hashearString(contrasenia);
  }

  private setSession(authResult) {
    //const expiresAt = moment().add(authResult.expiresIn,'second');

    localStorage.setItem('auth_token', authResult.token);
    localStorage.setItem('auth_Refresh_token', authResult.refreshToken);
}  

  login(usuarioFromForm) {

    var usuario;
    var dataToken;

    this.http.post<any>(environment.UrlBaseApi +'Authenticate/Login', { username: usuarioFromForm.email, 
      password: this.encriptarContrasenia(usuarioFromForm.password) }, 
      {headers: new HttpHeaders({ 'Content-Type': 'application/json' })})
      .subscribe(
        data => {
          console.log(data)
          dataToken = data
          this.setSession(data)
          this.obtenerDetalleUsuario(usuarioFromForm.email).subscribe(
            data=>{
              usuario = data;
              //this._currentUser = new BehaviorSubject(usuario)
              /* this._currentUser.isStopped = false;
              this._currentUser.closed = false; */
              //this._currentUser.lift()
              this._currentUser.next(usuario);

            }, 
            (error) => {
              throw error
            }
          )
        },
        (error) => {
          throw error
        }
      )
  }

  getUserSubject() {
    return this._currentUser.asObservable();
  }

  isLoggedIn() {
    return !!this._currentUser.value;
  }

  obtenerDetalleUsuario(usuario: string): Observable<any>{

    return this.http.get<any>(environment.UrlBaseApi + `Authenticate/user/${usuario}`);
 
  }

  logout() {

      localStorage.removeItem('auth_token')
      localStorage.removeItem('auth_Refresh_token')
      
      this.router.navigate(['/login'])

      this._currentUser.next(null);
  }

Current user is used to display manus and headers in appComponent.

<app-menu *ngIf="currentUser"> <ion-header [translucent]="false" *ngIf="currentUser">

Any suggestion?

EDIT:

After trying different things, I notice that if I comment the following line in the logout mehod:

this._currentUser.next(null);

Application navigates to login page and inputs work. But since menus and header depends on subject, they are shown.

Any advice on how to fix subject?

2

2 Answers

1
votes

Since currentUser is an Observable, it should be used with AsyncPipe in order to subscribe to it and receive its inner value as demonstrated below:

<app-menu *ngIf="currentUser | async">
0
votes

Are you unsubscribing from this.authService.currentUser when the component is destroyed?

Component code:

destroyed$ = new Subject();

this.authService.currentUser.pipe(
   takeUntil(this.destroyed$)
).subscribe(...)

ngOnDestroy() {
   this.destroyed$.next();
   this.destroyed$.complete();
}