nativescript-geolocation
nativescript-geolocation copied to clipboard
How to prevent multiple watchLocation listeners ?
Hi,
Is there some option to stop all active watchLocation listeners started from the app ?
In my case I have component which starts watchLocation listener every time when is visited. The problem is the previous listeners don't stop to listen for gps location ( and i have multiple active listeners for gps location ).
How can i stop them without to know their watch IDs ?
I tried with simple check :
if ( !this.watchId ) {
this.watchId = geolocation.watchLocation(this.locationReceived, this.error, {
desiredAccuracy: 20,
updateDistance: 0,
minimumUpdateTime: 15000,
maximumAge: 6000
});
}
But every time this watchID is different for each new visit in the component and accordingly it`s not created ( this doesn't work ) .
Thanks for help !
Hi @Syler921,
It's a very nice idea. We could add something like clearAllWatchIds() similar to the Demo App logic. I've labeled that with the 'good first time' label.
here:
import {Injectable} from "@angular/core";
import {Observable} from "rxjs/Observable";
import {Subscription} from "rxjs/Subscription";
import {interval} from 'rxjs/observable/interval'
import {timer} from 'rxjs/observable/timer'
import {delayWhen, distinctUntilChanged, flatMap, map, retryWhen, share, switchMap, tap} from 'rxjs/operators'
import {clearWatch, enableLocationRequest, Location as GPSLocation, watchLocation} from "nativescript-geolocation";
import {Accuracy} from "tns-core-modules/ui/enums";
import {Analytics} from "../utils/analytics";
export const DEFAULT_OPTIONS = {
desiredAccuracy: Accuracy.high,
minimumUpdateTime: 1000,
iosAllowsBackgroundLocationUpdates: true
};
export {Location as GPSLocation} from "nativescript-geolocation";
@Injectable()
export class LocationService {
private _lastLocation: GPSLocation;
private locationEvents: Observable<GPSLocation>;
public constructor() {
this.locationEvents = this.askForLocationPermissions()
.pipe(
flatMap(() => new Observable((sub) => {
let watchId = -1;
try {
watchId = watchLocation(
(loc) => {
this._lastLocation = loc;
console.log(`NEW! lat: ${loc.latitude} lon: ${loc.longitude}`)
sub.next(loc);
},
(error) => {
sub.error(error);
},
DEFAULT_OPTIONS);
console.info(`[watchLocation ${watchId}] Subscribed`);
} catch(error) {
sub.error(error);
}
return () => {
if (watchId != -1) {
console.info(`[watchLocation ${watchId}] Unsubscribed`);
clearWatch(watchId);
}
};
})),
switchMap((loc: GPSLocation) => interval(1000)
.pipe(
map(() => loc),
tap((loc) => console.log(`lat: ${loc.latitude} lon: ${loc.longitude}`)))),
share());
}
public get lastLocation(): GPSLocation {
return this._lastLocation;
}
/**
* Keeps the location updated by calling the given callback, the
* subscription is returned.
*/
public keepLocationUpdated(callback: (loc: GPSLocation) => void): Subscription {
return this.watchLocation()
.pipe(
retryWhen((errors) => errors
.pipe(
tap((error) => Analytics.logError(error, "Error in keepLocationUpdated, attempting retry in 1 second")),
delayWhen(() => timer(1000)))),
distinctUntilChanged((x, y) => x.latitude !== y.latitude || x.longitude !== y.longitude))
.subscribe(
(loc) => callback(loc),
(error) => Analytics.logError(error, "Fatal error in keepLocationUpdated"));
}
/**
* Begins watching the current location.
*/
public watchLocation(): Observable<GPSLocation> {
return this.locationEvents;
}
/**
* Asks for location permissions, returns either true or an error.
*/
public askForLocationPermissions(): Observable<boolean> {
return new Observable((sub) => {
enableLocationRequest()
.then(() => {
sub.next(true);
sub.complete();
})
.catch(() => sub.error(new Error('Location services not enabled')));
});
}
}
@briandilley how about a vanilla js example
@devyaz - no
On Sat, Sep 22, 2018, 2:16 AM devyaz [email protected] wrote:
@briandilley https://github.com/briandilley how about a vanilla js example
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/NativeScript/nativescript-geolocation/issues/46#issuecomment-423729747, or mute the thread https://github.com/notifications/unsubscribe-auth/ABBNz4Nun_9ZcB8lz0lMQQJ34ezeACR1ks5udgAHgaJpZM4LZP2f .
Hey I am quite new to NS and Android and I also need this feature as well. I am thinking of making an improvisation using a for loop. Since the watchID is provided via increment, I am thinking of iterating for all previous values that were used for the watchID and passing them in clearWatch. The problem here is that I need to first get the watchID (which means starting a watchLocation) and afterwards I can clear all previous watchLocation listeners. Is there a way to get the watchID (the current value of watchIdCounter) without starting an watchLocation.
Another option would be to get access to the locationListeners object and remove all existing listeners.