RiesvGeffen
RiesvGeffen

Reputation: 1589

*ngIf not working as expected with observable

So I have these 2 buttons:

<a class="router-link nav-item" routerLink="/login" *ngIf="!isLoggedIn$ | async">
  Login
</a>
<a class="router-link nav-item" (click)="onLogout()" *ngIf="isLoggedIn$ | async">
  Logout
</a>

And the logout button works perfectly, as soon as the user is logged in the button appears. But the login button never appears.

This is the code behind the isLoggedIn$:

isLoggedIn$: Observable<boolean>;

ngOnInit() {
  this.isLoggedIn$ = this.authService.isLoggedIn;
}

AuthService:

private loggedIn = new BehaviorSubject<boolean>(false);

get isLoggedIn() {
  return this.loggedIn.asObservable();
}

Hope this is enough information and the problem is clear, thanks in advance!

Upvotes: 40

Views: 38077

Answers (5)

Digvijay Lawand
Digvijay Lawand

Reputation: 1

You can also subscribe to isLoggedIn() function instead of using obsevable with async pipe:

isLoggedIn: boolean;

ngOnInit() {
  this.isLoggedIn = this.authService.isLoggedIn().subscribe(res => {
       this.isLoggedIn = res;
  });
}

Now you can just use isLoggedIn in Html:

<a class="router-link nav-item" routerLink="/login" *ngIf="!isLoggedIn">
 Login
</a>

<a class="router-link nav-item" (click)="onLogout()" *ngIf="isLoggedIn">
Logout
</a>

Upvotes: 0

TruncatedCoDr
TruncatedCoDr

Reputation: 370

In Angular version 14, this works for me:

<a class="router-link nav-item" routerLink="/login" *ngIf="(isLoggedIn$ | async) === false">
  Login
</a>
<a class="router-link nav-item" (click)="onLogout()" *ngIf="isLoggedIn$ | async">
  Logout
</a>

Upvotes: 0

proximab
proximab

Reputation: 2463

I like the answer with *ngIf and Else approach, but your version can also be optimized to prevent double subscription.

<ng-container *ngIf="{ isLoggedIn: (isLoggedIn$ | async) } as observables">
  <a class="router-link nav-item" routerLink="/login" *ngIf="!observables.isLoggedIn">
    Login
  </a>
  <a class="router-link nav-item" (click)="onLogout()" *ngIf="observables.isLoggedIn">
  Logout
  </a>
</ng-container>

Upvotes: 6

Tomasz Kula
Tomasz Kula

Reputation: 16837

Put the async pipe in parenthesis.

<a class="router-link nav-item" routerLink="/login" *ngIf="!(isLoggedIn$ | async)">
  Login
</a>
<a class="router-link nav-item" (click)="onLogout()" *ngIf="isLoggedIn$ | async">
  Logout
</a>

Upvotes: 73

Adrian F&#226;ciu
Adrian F&#226;ciu

Reputation: 12552

You can also refactor to use the else part of ngIf directive:

<a class="router-link nav-item" (click)="onLogout()" *ngIf="isLoggedIn$ | async; else loginBlock">
    Logout
</a>
<ng-template #loginBlock>
    <a class="router-link nav-item" routerLink="/login">
        Login
    </a>
</ng-template>

You can see more examples in the docs.

Upvotes: 10

Related Questions