0

I'm wondering how I can execute an http request where I update the profile view within the Angular2 Zone. In my top level profile component I'm currently doing a single simple http request using authHttp:

export class ProfileComponent implements OnInit {
    constructor(
        private auth: Auth,
        private authHttp: AuthHttp) {}

    ngOnInit() {
        // update profile information
        let headers: any = {
            'Accept': 'application/json',
            'Content-Type': 'application/json'
        };

        this.authHttp
            .get('https://' + myConfig.domain + '/api/v2/users/' + this.auth.userProfile.user_id, {headers: headers})
            .map(response => response.json())
            .subscribe(
                response => {
                    this.auth.userProfile = response;
                    localStorage.setItem('profile', JSON.stringify(response));
                },
                error => console.log(error.json().message)
            );

    }
}

The issue is that since this request is asynchronous, the profile page loads before this request is fulfilled and the profile is updated. What happens is on the first time I click refresh nothing happens, because the old data is loaded into profile and the new data AFTER. Then second time I hit refresh everything works, because it's only then using the new data loaded from the last request.

Is this issue solvable using NgZone? Can I somehow include this request into the zone so when it finishes it reevaluates the component tree?

Syntactic Fructose
  • 18,936
  • 23
  • 91
  • 177
  • I'm still a bit confused by this. What isn't updating? Your View? Are you binding to the auth.userProfile in your View? And it's not updating when the request through authHttp comes back? – smoyer Jan 16 '17 at 19:12
  • @Steveadoo I'm passing some pieces of data from `auth.userProfile` as input into another component in the template of the profile component, so it's passing the old data in as input before the `auth.userProfile` can be updated by the http request – Syntactic Fructose Jan 16 '17 at 19:13
  • How do you know it's a zone issue? Looking at AuthHttp, it doesn't look like it'd run outside of angular's zone. If you pass the auth.userProfile in as @Input() properties into your other component, it should automatically update then when you change it. Do you happen to be reading the @Input properties inside of the ngOnInit in this other component? – smoyer Jan 16 '17 at 19:18
  • @Steveadoo I am indeed reading and using the `@input` properties in the other components NgOnInit, would that be the root cause of the issue? – Syntactic Fructose Jan 16 '17 at 19:21
  • Yessir, try to make them setters, and then call some sort of update method on it. I will post an answer that's more detailed. – smoyer Jan 16 '17 at 19:24

1 Answers1

1

From your comments I don't think it has anything to do with Zones. You need to update your secondary component when your @Input properties change.

export class SecondaryComponent {

    private _myProperty: any;
    @Input()
    set myProperty(val: any) {
        this._myProperty = val;
        this.update();
    }

    update() { //instead of ngOnInit just use this
        //do stuff with _myProperty now
    }

}

However, why can't you just bind to the auth.userProfile field inside that secondary component? Unless you transform the data somehow inside your secondary components ngOnInit method, that would probably be easier.

smoyer
  • 7,932
  • 3
  • 17
  • 26