Angular2 canActivate() calling async function
canActivate
needs to return an Observable
that completes:
@Injectable()export class AuthGuard implements CanActivate { constructor(private auth: AngularFireAuth, private router: Router) {} canActivate(route:ActivatedRouteSnapshot, state:RouterStateSnapshot):Observable<boolean>|boolean { return this.auth.map((auth) => { if (auth) { console.log('authenticated'); return true; } console.log('not authenticated'); this.router.navigateByUrl('/login'); return false; }).first(); // this might not be necessary - ensure `first` is imported if you use it }}
There is a return
missing and I use map()
instead of subscribe()
because subscribe()
returns a Subscription
not an Observable
You might use Observable
to handle the async logic part. Here is the code I test for example:
import { Injectable } from '@angular/core';import { CanActivate } from '@angular/router';import { Observable } from 'rxjs/Observable';import { DetailService } from './detail.service';@Injectable()export class DetailGuard implements CanActivate { constructor( private detailService: DetailService ) {} public canActivate(): boolean|Observable<boolean> { if (this.detailService.tempData) { return true; } else { console.log('loading...'); return new Observable<boolean>((observer) => { setTimeout(() => { console.log('done!'); this.detailService.tempData = [1, 2, 3]; observer.next(true); observer.complete(); }, 1000 * 5); }); } }}