Reputation: 790
I want to redirect to my home component after authentication. The redirection is successful, but the home component does not render. If I move this.router.navigate outside the subscribe block, it will render properly.
export class LoginComponent implements AfterViewInit {
constructor(private router: Router,
private authService: AuthenticationService) {
this.authService.authenticationStream().subscribe(isAuthenticated => {
if (isAuthenticated) {
this.router.navigate(['/home']);
}
});
}
}
In chrome dev tools, I can see all of the home component's template except for a ngFor block:
<md-grid-tile *ngFor="let tile of CONFIG.tiles">
{{ tile }}
</md-grid-tile>
I can verify CONFIG.tiles is populated.
Why would the ngFor block not be rendered after navigation, specfically from a navigate call inside of an Observable subscription?
EDIT: Adding AuthenticationService code:
export class AuthenticationService {
constructor(private http: HttpService,
private store: Store<AppStore>) {
}
authenticate(): void {
let uri = 'http://uri.com'
this.http.post(uri).subscribe(() => {
// Dispatch event to ngrx store if user is successfully authenticated
this.store.dispatch({type: AUTHENTICATED});
});
}
authenticationStream(): Observable<boolean> {
// Emits events from dispatch calls
return <Observable<boolean>> this.store.select(AUTHENTICATION);
}
}
Upvotes: 2
Views: 1836
Reputation: 657546
It sounds like authenticationStream
emits events outside Angulars zone which breaks change detection and would lead to the behavior you described.
You can use zone.run()
to force execution back into Angulars zone:
export class LoginComponent implements AfterViewInit {
constructor(private router: Router,
private authService: AuthenticationService
zone: NgZone) {
this.authService.authenticationStream().subscribe(isAuthenticated => {
if (isAuthenticated) {
zone.run(() => this.router.navigate(['/home']));
}
});
}
}
Upvotes: 3