Search code examples
angularzonezonejs

Execute http request inside NgZone with Angular2


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?


Solution

  • 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.