Reputation: 783
I am working with a project in Angular 2. I want to get the current location of the user (which is working), but the view does not update after running.
I have placed the code to get the location in a service:
getCurrentLocation(): Observable<Coordinates> {
return new Observable((ob) => navigator.geolocation.getCurrentPosition(s => ob.next(s.coords), e => ob.next(null)));
}
I am calling the service from onInit:
ngOnInit() {
this.title = 'Title 1';
this.locationService.getCurrentLocation().subscribe(r => {
this.title = 'Title 2';
alert(`this tells me it has reurned with ${r.latitude}, ${r.longitude}`);
});
}
The location, Observable, etc are all working. The Alert pops up, it shows the location, but the view stays on "Title 1".
Am I missing something?
Update:
I created a new project, and just put this in it:
constructor() {
this.title = 'Title 1';
this.getCurrentLocation().subscribe(r => {
this.title = 'Title 2';
alert('got loc');
});
}
getCurrentLocation(): Observable<Coordinates> {
return new Observable((ob) => navigator.geolocation.getCurrentPosition(s => ob.next(s.coords), e => ob.next(null)));
}
It is working here.
There must be something else in my project that is breaking something.
Update 2:
So, I deleted the component, created a new one, And it seems to be working.
I don't know why...
Upvotes: 1
Views: 2380
Reputation: 2191
As another answer already points out, it seems to be a change detection issue. However, instead of NgZone
, I think you might get better mileage out of using ChangeDetectorRef.detectChanges
to trigger local refresh of the bindings associated with your component. (In the example at the above-linked doc page, it shows use of detach
alongside detectChanges
, but you can use the latter on its own.)
Upvotes: 3
Reputation: 2629
It seems a change detection issue. Change detection is fired on every browser event, timeout or http request.
The case is that your function is asyncronous and is its callback is not detected for Angular and consequently it doesn't fires the change detection event in order to update the view.
In order to solve this you will have to wrap this function into the angular zone. See this code:
import zone:
import { NgZone } from '@angular/core';
Inject the service ngZone:
constructor(private zone: NgZone) {
....
}
And finally add this to your function:
ngOnInit() {
this.title = 'Title 1';
this.locationService.getCurrentLocation().subscribe(r => {
this.zone.run(
() => {
this.title = 'Title 2';
}
)
alert(`this tells me it has reurned with ${r.latitude}, ${r.longitude}`);
});
}
Hope this helps.
Upvotes: 1