Im using expo-location to monitor my users location as it updates
The Location.watchPositionAsync(options, callback)
function in particular.
Its outputting the correct location but its not setting that output as the state using setLocation
location
is returning the following :
Object {
"remove": [Function remove],
}
setLocation
and location
are being stored in a context provider
My code is as follows :
App.js
useEffect(() => {
console.log('hi')
_getLocationAsync = async () => {
let { status } = await Permissions.askAsync(Permissions.LOCATION)
if (status !== 'granted') {
console.log('debieeed')
}
let locations = await Location.watchPositionAsync({ accuracy: Location.Accuracy.Balanced, timeInterval: 10000, distanceInterval: 1 }, (loc) => setLocation(loc.coords));
console.log(locations)
}
_getLocationAsync()
}, [])
Im using expo-location to monitor my users location as it updates
The Location.watchPositionAsync(options, callback)
function in particular.
Its outputting the correct location but its not setting that output as the state using setLocation
location
is returning the following :
Object {
"remove": [Function remove],
}
setLocation
and location
are being stored in a context provider
My code is as follows :
App.js
useEffect(() => {
console.log('hi')
_getLocationAsync = async () => {
let { status } = await Permissions.askAsync(Permissions.LOCATION)
if (status !== 'granted') {
console.log('debieeed')
}
let locations = await Location.watchPositionAsync({ accuracy: Location.Accuracy.Balanced, timeInterval: 10000, distanceInterval: 1 }, (loc) => setLocation(loc.coords));
console.log(locations)
}
_getLocationAsync()
}, [])
Share
Improve this question
edited Aug 2, 2020 at 17:02
0xD1x0n
asked Aug 1, 2020 at 23:15
0xD1x0n0xD1x0n
6456 gold badges13 silver badges37 bronze badges
5 Answers
Reset to default 5I had the same problem not getting any location with watchPositionAsync()
It seems there is a bug (or it is intended this way, idk). You must set accuracy to high to get location object. It does not work with other accuracy options (as it also does not work with default).
let location = await Location.watchPositionAsync(
{accuracy:Location.Accuracy.High},
(loc) => {console.log(loc)}
);
Hope this helps someone, I lost an hour on this :)
This question is old, but for anyone still interested:
The watchPositionAsync
function does not return the location directly; instead, it returns a LocationSubscription object. This object has a remove
method that allows you to stop receiving updates. In most cases, you will use this method during the cleanup phase of the useEffect
hook.
To receive locations, you need to provide a callback
function as a parameter after the options
parameter. Keep in mind that the frequency of updates depends on the values passed to the options
parameter. During development, using high accuracy, low time intervals, and small distance intervals can be useful for testing your callback
function. However, make sure to adjust these parameters appropriately for production.
Here's an example implementation:
useEffect(() => {( async () => {
const { status } = await requestForegroundPermissionsAsync()
if (status !== 'granted') {
console.log('Permission to access location was denied')
} else {
const locationSubscription = await watchPositionAsync({
accuracy: Accuracy.Highest,
timeInterval: 1000,
distanceInterval: 1,
}, (location) => {
setLocation(location)
console.log('New location update: ' + location.coords.latitude + ', ' + location.coords.longitude)
})
} return () => locationSubscription.remove()
})()}, [])
I fixed my issue by simply making a deep copy of the location returned
Please correct me if my logic is wrong
I changed this
let locations = await Location.watchPositionAsync({ accuracy: Location.Accuracy.Balanced, timeInterval: 10000, distanceInterval: 1 }, (loc) => setLocation(loc.coords));
To this
let locations = await Location.watchPositionAsync({ accuracy: Location.Accuracy.Lowest, distanceInterval: 2000 }, loc => setLocation(JSON.parse(JSON.stringify(loc.coords))));
Where JSON.parse(JSON.stringify(loc.coords))
is making a deep copy of the location data
export default function App() {
const [location, setLocation] = useState(null);
const [status, requestPermission] = Location.useForegroundPermissions();
useEffect(() => {
(async () => {
let { status } = await Location.requestForegroundPermissionsAsync();
if (status !== 'granted') {
setErrorMsg('Permission to access location was denied');
return;
}
let location = await Location.getCurrentPositionAsync({});
setLocation(location.coords);
let backPerm = await Location.requestBackgroundPermissionsAsync();
let locations = await Location.watchPositionAsync({
accuracy: Location.Accuracy.High,
distanceInterval: 2,
timeInterval: 3000
},
(loc) => { setLocation(loc.coords) });
})(); }
import React, { useState, useEffect } from 'react';
import { Platform, Text, View, StyleSheet } from 'react-native';
import Device from 'expo-device';
import * as Location from 'expo-location';
export default function App() {
const [location, setLocation] = useState(null);
const [errorMsg, setErrorMsg] = useState(null);
useEffect(() => {
(async () => {
if (Platform.OS === 'android' && !Device.isDevice) {
setErrorMsg(
'Oops, this will not work on Snack in an Android Emulator. Try it on your device!'
);
return;
}
let { status } = await Location.requestForegroundPermissionsAsync();
if (status !== 'granted') {
setErrorMsg('Permission to access location was denied');
return;
}
//let location = await Location.getCurrentPositionAsync({});
let foregroundSubscrition= Location.watchPositionAsync(
{
// Tracking options
accuracy: Location.Accuracy.High,
distanceInterval: 10,
},
(location) => {setLocation(location);}
)
})();
}, []);
let text = 'Waiting..';
if (errorMsg) {
text = errorMsg;
} else if (location) {
text = JSON.stringify(location);
}
return (
<View style={styles.container}>
<Text style={styles.paragraph}>{text}</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
padding: 20,
},
paragraph: {
fontSize: 18,
textAlign: 'center',
},
});