2

I am developing a simple POC to display the current position. The program receives the information from the geolocation.watchLocation however the location is not bind and displayed on the screen until I press the button STOP Monitoring. To be noted that the log is correctly showing the coordinates

JS: Start Monitoring ...
JS: Location: 49.6411839:6.0040451
JS: Stop Monitoring ...

import {Component} from "@angular/core";
import {Router} from "@angular/router";
import geolocation = require("nativescript-geolocation");

@Component({
    selector: "TrackingPageSelector",
    template:`
    <StackLayout>
        <Button [text]="watchId==0 ? 'Start Monitoring' : 'Stop Monitoring'" (tap)="buttonStartStopTap()"></Button>
        <Label class="labelValue" [text]="latitude"> </Label>
        <Label class="labelValue" [text]="longitude"> </Label>
    </StackLayout>`
})

export class TrackingPageComponent {
    latitude: number = 0;
    longitude: number = 0;
    watchId: number = 0;
    constructor(private router: Router) {}

    ngOnInit() {
        if (!geolocation.isEnabled()) geolocation.enableLocationRequest();
    }

    public buttonStartStopTap() {
        if (this.watchId != 0) {
            console.log('Stop Monitoring ...');
            geolocation.clearWatch(this.watchId);
            this.watchId = 0;
        } else {
            console.log('Start Monitoring ...');
            let _self = this;
            this.watchId = geolocation.watchLocation(
                function (loc) {
                    if (loc) {
                        _self.latitude = loc.latitude;
                        _self.longitude = loc.longitude;
                        console.log(`Location: ${_self.latitude}:${_self.longitude}`);
                    }
                },
                function(e){
                    this.errorMsg = e.message;
                },
                {desiredAccuracy: 3, updateDistance: 10, minimumUpdateTime: 1000 * 3}); // Should update every X seconds
        }
    }
}

1 Answer 1

2

If you use ()=> instead of function () then you don't need the _self hack. It looks like you need to invoke change detection manually. NgZone seems not to cover geolocation.watchLocation()

 constructor(private cdRef:ChangeDetectorRef) {}

 ...

        this.watchId = geolocation.watchLocation(
            (loc) => {
                if (loc) {
                    this.latitude = loc.latitude;
                    this.longitude = loc.longitude;
                    this.cdRef.detectChanges();
                    console.log(`Location: ${this.latitude}:${this.longitude}`);
                }
            },
            (e) => {
                this.errorMsg = e.message;
            },

or alternatively zone.run(() => ...) like

 constructor(private zone:NgZone) {}

 ...

        this.watchId = geolocation.watchLocation(
            (loc) => {
                if (loc) {
                  this.zone.run(() => {
                    this.latitude = loc.latitude;
                    this.longitude = loc.longitude;

                    console.log(`Location: ${this.latitude}:${this.longitude}`);
                   });
                }
            },
            (e) => {
                this.errorMsg = e.message;
            },

If you only change local fields cdRef.detectChanges() is the better option, if you call methods that might modify some state outside of the current component, zone.run(...) is the better option.

Sign up to request clarification or add additional context in comments.

2 Comments

Indeed the solution provided works! I implemented the detectChanges proposal. Thank you for your help!
If this answers your question, can you please mark the question as answered by accepting my answer using the white check mark below the up-down-vote buttons, to make it obvious that the problem is solved? Thanks!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.