I have an Angular guard
that uses data from injected service to determine if a route can be accessed, like so:
@Injectable({
providedIn: 'root'
})
export class MyGuard implements CanActivate {
constructor(private someService: SomeService, private router: Router) { console.log('in guard ctor'); } // CONSOLE LOG
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
return this.someService.data$.pipe(
tap(u => console.log('from guard: ', d)), // CONSOLE LOG
map(data => {
if (!data) {
this.router.navigate(['/whatever']);
return;
}
else
return true;
},
err => {
this.router.navigate(['/whatever']);
return err;
})
);
}
}
The service, with unimportant stuff abstracted, looks something like this:
@Injectable({
providedIn: 'root'
})
export class SomeService {
private dataSource = new BehaviorSubject<MyData>(null);
public data$ = this.dataSource.asObservable().pipe(map(u => cloneData(u)));
constructor(private apiService: SomeApiService,
authorizeService: AuthorizeService) {
authorizeService.isAuthenticated()
.pipe(
tap(auth => console.log('in data service ctor')), // CONSOLE LOG
filter(x => !!x),
mergeMap(() => apiService.get())
)
.subscribe(res => {
console.log('data arrived: ', res); // CONSOLE LOG
this.dataSource.next(res);
});
}
}
This is the sequence of console logs: in guard ctor from guard: undefined in data service ctor data arrived: {...}
It's obvious that the guard gets instantiated before data service. How can I prevent this? Both are provided in root.