Lance Hardwood
Lance Hardwood

Reputation: 790

Router navigate redirect after authentication does not render component

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

Answers (1)

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

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

Related Questions