13

I have the following BehaviorSubject in a service:

  isAuthenticated = new BehaviorSubject<boolean>(false);

And I am using it as follows in a component:

  authenticated: Observable<boolean>;

  constructor(private accountService: AccountService) { }

  ngOnInit() {
    this.authenticated = this.accountService.isAuthenticated.asObservable();
  }

And in the template I do something like :

  <li class="login-button" *ngIf="!authenticated | async">
    <a (click)="authenticate()">Log in</a>
  </li>
  <li *ngIf="authenticated | async">
    <a>Logged in</a>
  </li>

The issue is that I dont see any of the two li, although the assumption is that the first one should appear since I am assigning the initial value of the Subject to false.

What am I doing wrong?

AngularDebutant
  • 1,436
  • 5
  • 19
  • 41
  • you should be setting the value by calling the `next` method of the `BehaviourSubject` – Aravind Jan 18 '18 at 10:45
  • 2
    Can you try putting the first expression into parenthesis like `!(authenticated | async)` to make sure it's using the `async` pipe on the Observable and not the result of `!authenticated` – martin Jan 18 '18 at 10:46
  • @martin that's it! Thank you! – AngularDebutant Jan 18 '18 at 10:50
  • @Aravind, there is no need to call `next` for BehaviourSubject ! – AngularDebutant Jan 18 '18 at 10:51
  • The initial value for the BehaviorSubject is 'false', which in your check ... *ngIf="authenticated" isn't going to give you anything. So yes it has a value, but not one that you code will find useful. – rrd Jan 18 '18 at 10:54

2 Answers2

16

I suspect its the order of operations - you need parenthesis around your subscription:

<li class="login-button" *ngIf="!(authenticated | async)">
Michael Kang
  • 52,003
  • 16
  • 103
  • 135
5

I thought of posting a solution using ng-if-else which is maybe even more intuitive in your particular case:

<li class="login-button" *ngIf="(authenticated | async); else unauthenticated">
  <a>Logged in</a>
</li>
<ng-template #unauthenticated>
  <a (click)="authenticate()">Log in</a>
</ng-template>

Alternatively you could puth both cases inside a ng-template:

<li class="login-button" *ngIf="(authenticated | async); then authenticated else unauthenticated"></li>
<ng-template #authenticated ><a>Logged in</a></ng-template>
<ng-template #unauthenticated><a (click)="authenticate()">Log in</a></ng-template>

Hope it is of any use to other people ending up here.

Wilt
  • 41,477
  • 12
  • 152
  • 203