Monitoring API Response from angular

114 Views Asked by At

I'm trying to monitor an api response to know if the user is currently logged in or not. To do so, I'm sending a get request to /api/status along with the http-only cookie. the endpoint should respond with my userid if I am currently logged in. If am logged in, angular should not show the login/register links. My code is as follows:

export class HeaderComponent implements OnInit {
  authService = inject(AuthService)

  isLoggedIn$ = new BehaviorSubject<Boolean>(false);

  authenticationStatus!: Observable<HttpResponse<object>>;

  constructor() {
    this.authenticationStatus = this.authService.authStatus()

  }
  ngOnInit(): void {
    this.authenticationStatus.subscribe({
      next: (res: any) => {
        if (res.body) {
          const userId = res.body.message;
          console.log("User ID: ", userId);
          this.isLoggedIn$.next(true)
          console.log(this.isLoggedIn$.value);
        } else this.isLoggedIn$.next(false)
      },
      error: (err) => {
        console.log(err)
        this.isLoggedIn$.next(false)
      }
    });
  }
}

authStatus() : Observable<HttpResponse>{ return this.http.get(${apiUrls.authServiceApi}/status, { observe: 'response', withCredentials: true }); }

then in the template, I use:

    <ng-container *ngIf="!isLoggedIn$.value">
      <span
        [routerLink]="['/login']"
        routerLinkActive="router-link-active"
        class="text-xl cursor-pointer text-gray-200 font-bold m-3 hover:underline hover:text-indigo-200"
        >Login</span
      >
      <span
        [routerLink]="['/register']"
        routerLinkActive="router-link-active"
        class="text-xl cursor-pointer text-gray-200 font-bold m-3 hover:underline hover:text-indigo-200"
        >Register</span
      >
</ng-container>

The problem is that the login/register links don't disappear after logging in till I refresh the page. Any ideas?

I'm expecting the isLoggedIn variable to be updated.

3

There are 3 best solutions below

2
Alpine A110R On

You have isLoggedIn$.value in your template. I suspect .value on your observable. I dont think it returns the last emitted value.

You can use async pipe to subscribe to an observable.

<ng-container *ngIf="!isLoggedIn$ | async">
1
salhi mustapha On

The asObservable() method of BehaviorSubject is used to convert it into an observable, allowing only observation and prohibiting direct calls to next(), error(), or complete() methods. This is useful when you want to expose only the observable part of the BehaviorSubject to consumers, preventing them from modifying its state directly.

 private isLoggedInSource = new BehaviorSubject<boolean|null>(null);
 //Creates a new Observable with this Subject as the source
 isLoggedIn$ = isLoggedInSource.asObservable();
 this.isLoggedInSource.next(true);
 <ng-container *ngIf="!isLoggedIn$ | async">
18
JSmith On

I would try:

export class HeaderComponent implements OnInit {
  authService = inject(AuthService)

  isLoggedIn$ = new BehaviorSubject<Boolean>(false);

  ngOnInit(): void {
    console.log('IS INIT');
    this.authService.authStatus().pipe(
      tap( console.log ),
      tap( res => {
          this.isLoggedIn$.next(!!res?.body)
      } )
    ).subscribe(
      () => {},
      ( err ) => {
        console.log( err );
        this.isLoggedIn$.next( false );
      }
    )
  }
}

and in the html

<ng-container *ngIf="!(isLoggedIn$ | async)">

this is more or less the same but can you give what's you result in the console?