简体   繁体   中英

angular component loading before app.component

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 => {
....
})
)

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);
    }));
  }
}

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM