3

I want to get the user data in the main root component of the app and then after user data is stored into service to continue loading other components. How can I achieve this? Currently, I have something like this:

@Injectable()
export class UserService {

user: Subject<User> = new BehaviorSubject(new User());

constructor(private _httpService: HTTPService){}

getUser(){
    return this.user;
}

getUserFromAPI(){
    this._httpService.get('user')
        .map(data => data.json())
        .subscribe(data => {
            this.user.next(data);
        });
}

But with this way, it means that I need to get the user on every other place through the Observable which I don't want. I want to have a static access. Currently, I'm getting the user:

this._userService.getUser().subscribe(data => {
        this.user = data;
    });
Igor Janković
  • 5,494
  • 6
  • 32
  • 46

1 Answers1

3

You can use APP_INITIALIZER Angularjs2 - preload server configuration before the application starts for Angular to wait rendering any components before the data is available

or you can just use *ngIf to prevent components being rendered before the data is available

<ng-container *ngIf="data">
  <child1></child1>
  <child2></child2>
</ng-container>
Community
  • 1
  • 1
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • With the *ngIf I'm getting the error Cannot find primary outlet to load SomeComponent. Do you know how I can fix this? – Igor Janković Dec 29 '16 at 09:05
  • If the component is added by the router use a resolver https://angular.io/docs/ts/latest/guide/router.html#!#resolve-guard – Günter Zöchbauer Dec 29 '16 at 09:07
  • Correct me if I'm wrong, but as far as I know, root component isn't load through the router? – Igor Janković Dec 29 '16 at 09:09
  • Right, the root component isn't added by the router, but the question was about child components not being added before data is available. If your child components are added by the router, then you should use `resolve` to delay components being added until the data is available. – Günter Zöchbauer Dec 29 '16 at 09:10
  • But that is not handling on the one place. It's not a solution for what I've asked. That means that I need to go through every new route and add resolve. – Igor Janković Dec 29 '16 at 09:31
  • You can just add the same resolve to every route or use a componentless parent route with a resolver, where you put all root routes, then no component of a child route will be added as long as the resolver isn't completed. – Günter Zöchbauer Dec 29 '16 at 09:33
  • I don't think this is the correct way of doing it as you are making the whole application wait for all the data across components to get loaded, what if, the child component sits on some other view and not the landing view. The user has to still wait for the data where in his landing view is already ready. – Shubham Tiwari Feb 15 '18 at 01:06
  • @ShubhamTiwari I don't say you should do that. What my answer explains is, how to do it if you actually want to. I don't know what the point is in downvoting an answer just because it explains something you don't want to do. There are situations where you need exactly that even though the disadvantages are known. This is the reason `APP_INITIALIZER` exists. – Günter Zöchbauer Feb 15 '18 at 03:58
  • @Gunter: The reason it exist is because to make certain data available before the application get initialized in other words to wait for the data which may be required to get your application kick started and this answer would be more relevant to it. In the above question it may be relevant if the child component exist in the landing view itself but not in all scenarios. Nothing personal mate! It may help someone but it does not fit the bill for all the scenarios as explained earlier. – Shubham Tiwari Feb 15 '18 at 04:34