Reputation: 59
I wanted to be able to track user locations for some features in my application, but I want users to be able to turn off location if they want. I've been using expo-location
to find the users location, request permission and varies other things. But when I use watchPositionAsync, I can't remove it when the user turns it off the feature. I read the docs and it said that I could use remove() but I get the following error when I try to do that:
Unhandled promise rejection: TypeError: client.location.remove is not a function. (In 'client.location.remove()', 'client.location.remove' is undefined)
For reference client is just a global object which stores some settings for the user (It's so I don't have to keep fetching it over and over again).
client.js
let client = {
user: {},
location: null
};
tracking.js
import * as Location from 'expo-location';
export async function startTracking(client){
console.log('Starting tracking')
if(!client.location){
client.location = Location.watchPositionAsync({
accuracy: Location.Accuracy.Highest,
distanceInterval: 1,
timeInterval: 5000,
}, (loc) => {
console.log(loc)
});
}
}
export async function stopTracking(client){
console.log('Remove tracking')
await client.location.remove();
}
More information:
Upvotes: 3
Views: 3224
Reputation: 66
A straightforward and more generic implementation as a hook:
import * as Location from 'expo-location';
import { useEffect, useState } from 'react';
export const useUserLocation = () => {
const [userLocation, setUserLocation] = useState<Location.LocationObjectCoords | null>(null);
useEffect(() => {
let subscription: Location.LocationSubscription | null = null;
(async () => {
const { status } = await Location.requestForegroundPermissionsAsync();
if (status === 'granted') {
subscription = await Location.watchPositionAsync(
{ accuracy: Location.Accuracy.BestForNavigation },
({ coords }) => setUserLocation(coords),
);
} else {
console.log('Location permissions not granted');
}
})();
return () => {
subscription?.remove();
};
}, []);
return userLocation;
};
Upvotes: 0
Reputation: 1239
You are not waiting the returned object by the function watchPositionAsync.
Returns a promise resolving to a subscription object, which has one field
I take this source.
Try this code.
import * as Location from 'expo-location';
export async function startTracking(client){
console.log('Starting tracking')
if(!client.location){
client.location = await Location.watchPositionAsync({
accuracy: Location.Accuracy.Highest,
distanceInterval: 1,
timeInterval: 5000,
}, (loc) => {
console.log(loc)
});
}
}
export async function stopTracking(client){
console.log('Remove tracking')
await client.location.remove();
}
Upvotes: 5