Reputation: 1973
I'm injecting userService in app component because I don't want my service to be empty when I inject it in every component in my app. So, what I want to happen is to load app.component with the logged in user and then my component. What is actually happening is that the component is loaded before app.component and my user is undefined.
how to make app component load first?
also, i have app.module and 2 other modules core.module and shared.module
export class AppComponent implements OnInit {
@HostListener("window:beforeunload",["$event"])
loading = true;
constructor(public router: Router,
public userService: UserService,
private accountService: AccountService,
private toastr: ToastrService
) { }
ngOnInit() {
StorageHelper.getToken()
? this.getUserDetails()
: this.loading = false;
}
getUserDetails() {
this.accountService.getUserDetails().subscribe(res => {
this.userService.setCurrentUser(<User>res);
this.loading = false;
}, error => {
StorageHelper.killSession();
this.toastr.error('login error');
this.loading = false;
this.router.navigate([Urls.LOGIN]);
});
}
Component => getCurrentUser() -> null
export class MyComponent implements OnInit {
constructor(private userService: UserService,
private myService: MyService) {}
ngOnInit() {
this.getPolicies();
}
getPolicies() {
this.myService.getPolicies(this.userService.getCurrentUser().id).subscribe(res => {
....
})
)
Upvotes: 0
Views: 2291
Reputation: 265
I would advice you to have a look on prefetching components data:
https://angular.io/guide/router#resolve-pre-fetching-component-data
Like it was said in comment above - your problem is not in loading service before App. But if you want to resolve data before to render any other component - pre fetching will help you.
Upvotes: 1
Reputation: 497
Your problem is not when the userService is instantiated. It's the way you want to access the user details for the first time.
Since this.accountService.getUserDetails() is an observable, even though the userService is instantiated your this.userService.setCurrentUser(res); will be called latter.
To fix this you can use all kinds of methods: -you can youse a routerguard and have the component load only after this.accountService.getUserDetails() is completed
documentation: https://angular.io/api/router/CanActivate
ex:
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private accountService: AccountService,
private userService: UserService,
private router: Router) {
}
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
return this.accountService.getUserDetails().pipe(map(res => {
this.userService.setCurrentUser(res);
return true;
}), catchError(() => {
this.router.navigate(['/login']);
return of(false);
}));
}
}
Upvotes: 1