I have an Angular (5.2.3) app where I want to display a login/logout button in the upper right corner of the page. Behind the scenes, I try to log the user in silently using an external Open ID Connect provider. When the callback arrives, I want to display the user's name and a logout button. But alas, the view is never updated to reflect this.
Here's the component's view:
<ul class="navbar-nav">
<li class="nav-item" *ngIf="!loggedIn">
<a href="#" class="nav-link" (click)="login()">Login</a>
</li>
<li class="nav-item" *ngIf="loggedIn">
<a href="#" class="nav-link disabled" disabled>Hello, {{ name }}</a>
</li>
<li class="nav-item" *ngIf="loggedIn">
<a href="#" class="nav-link" (click)="logoff()">Logout</a>
</li>
</ul>
import {
Component,
OnInit,
SimpleChanges,
ApplicationRef,
ChangeDetectorRef,
NgZone
} from '@angular/core';
import {
OAuthService
} from 'angular-oauth2-oidc';
import {
SessionService
} from '../session.service';
@Component({
selector: 'app-navigation',
templateUrl: './navigation.component.html',
styleUrls: ['./navigation.component.css']
})
export class NavigationComponent implements OnInit {
name: string;
loggedIn: boolean;
constructor(private oauthService: OAuthService,
private sessionService: SessionService,
private applicationRef: ApplicationRef,
private zone: NgZone,
private cd: ChangeDetectorRef) {
//this.loggedIn = false;
}
ngOnInit() {
this.sessionService.state.subscribe(isLoggedIn => {
console.log('Detected a state change! User is logged in: ' + isLoggedIn);
this.zone.run(() => {
if (!isLoggedIn) {
this.name = null;
this.loggedIn = false;
console.log('User not logged in. Name is set to null');
} else {
const claims: any = this.oauthService.getIdentityClaims();
console.log(`Got claims. Name is now ${claims.name}`);
this.name = claims.name;
this.loggedIn = true;
}
});
this.cd.detectChanges();
this.applicationRef.tick();
});
this.sessionService.configureWithNewConfigApi();
}
public login() {}
public logoff() {}
}
console.log
calls are executed as expected, only the view is never updated.