list of Location.reverseGeocodeAsync in react-native is empty
I'm running in my android device with expo go
this is the part of code
const {
coords: { latitude, longitude },
} = await Location.getCurrentPositionAsync({ accuracy: 5 });
const location = await Location.reverseGeocodeAsync(
{ latitude, longitude },
{ useGoogleMaps: false }
);
console.log(location);
};
Related
unfortunately I am struggling with the hook lifecycle in react native.
I have two hooks at the top level.
const permission = useLocationPermission();
const location = useCurrentLocation(locationPermission);
The first one handles the location permission permission and asks the user to grand.
export default function useLocationPermission() {
const [hasLocationPermission, setHasLocationPermission] = useState(false);
const appState = useRef(AppState.currentState);
useEffect(() => {
hasPermission();
}, []);
const hasPermission = async () => {
const { granted } = await Location.getForegroundPermissionsAsync();
if (!granted) {
const { granted: request } =
await Location.requestForegroundPermissionsAsync();
if (!request) {
Alert.alert(
"Some Message"
);
setHasLocationPermission(false);
} else {
setHasLocationPermission(true);
}
} else {
setHasLocationPermission(true);
}
};
return hasLocationPermission;
}
The second one handles the current location.
export default function useCurrentLocation(hasPermission: boolean) {
const [currentLocation, setCurrentLocation] = useState<LatLng>(initLocation);
useEffect(() => {
console.log(hasPermission);
if (hasPermission) {
setWatcher();
getCurrentPosition().then((locationObject) => {
setCurrentLocation({
latitude: locationObject.coords.latitude,
longitude: locationObject.coords.longitude,
});
});
} else {
setCurrentLocation(initLocation);
}
}, []);
const getCurrentPosition = async () => {
return Location.getCurrentPositionAsync({});
};
const setWatcher = async () => {
await Location.watchPositionAsync({ distanceInterval: 5 }, (locaction) => {
setCurrentLocation({
latitude: locaction.coords.latitude,
longitude: locaction.coords.longitude,
});
});
};
return currentLocation;
}
My problem is that after the user has granted the permission. The location will not been updated anymore (still the initial location). It seems that the second hook is only called ones.
Is there any best practice to handle such situation. So the location will be updated and the watcher is set after the permission is set.
Thanks a lot.
Your list of dependencies for the effect that sets current location is empty. Since you are saying you want that effect to be dependant on hasPermission, set it to [hasPermission] instead.
How can I use the output of this component function outside its scope?
const abc = () => {
navigator.geolocation.getCurrentPosition(position => {
const { latitude, longitude } = position.coords;
// console.log({latitude, longitude}) this log gives the correct results
});
}
I want to use latitude and longitude values outside the function, how can I do that?
One option is to make abc return a Promise that contains the latitude and longitude.
const abc = () => {
return new Promise((resolve, reject) => {
navigator.geolocation.getCurrentPosition(position => {
const { latitude, longitude } = position.coords;
resolve({latitude, longitude});
});
});
}
then you can use it to save some state in a component:
function MyComponent() {
const [location, setLocation] = useState(null);
useEffect(() => {
const coords = await abc();
setLocation(coords);
});
return ... // use `location` in some components here
}
Note that the above code may have a typo. I didn't run this example.
The method below calls a weather API and since it needs to fetch API data before the component loads, it's placed in a created lifecycle hook.
getWeather() {
const lat = this.$store.getters.getLatitude;
const long = this.$store.getters.getLatitude;
console.log('lat is ' + lat);
let url =
'http://api.openweathermap.org/data/2.5/weather?lat=' +
lat +
'&lon=' +
long +
'&units=metric&APPID=' +
process.env.VUE_APP_OPEN_WEATHER_API_KEY;
axios
.get(url)
.then((response) => {
this.currentTemp = response.data.main.temp + '°C';
this.minTemp = response.data.main.temp_min + '°C';
this.maxTemp = response.data.main.temp_max + '°C';
this.pressure = response.data.main.pressure + 'hPa';
this.humidity = response.data.main.humidity + '%';
this.wind = response.data.wind.speed + 'm/s';
})
.catch((error) => {
console.log(error);
});
},
},
created() {
this.getWeather();
},
Vuex store
import Vue from 'vue';
import Vuex from 'vuex'
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
latitude: '',
longitude: '',
},
mutations: {
SET_LATITUDE(state, payload) {
state.latitude = payload
},
SET_LONGITUDE(state, payload) {
state.longitude = payload
}
},
actions: {
GET_DATA({ commit }) {
var self = this
.
.
.
// LOGIC TO GET USER DATA ( LAT AND LONG FROM DATABASE )
.
.
.
self.ddb_data = [...data.Items];
const latitude = self.ddb_data[0].user_meta_data.coordinates.latitude
const longitude = self.ddb_data[0].user_meta_data.coordinates.longitude
commit('SET_LATITUDE', latitude)
commit('SET_LONGITUDE', longitude)
}
});
}
});
});
}
} catch (e) {
console.log(e);
return;
}
},
},
},
getters: {
getLatitude(state) {
return state.latitude;
},
getLongitude(state) {
return state.longitude;
},
},
});
export default store;
The issue comes in getting the lat and long from the vuex getters i.e. $store.getters.getLatitude and $store.getters.getLongitude. It seems like the getters are not returning the data when used inside the method (after page is reloaded ). The getters seem to work when used in a computed property ( regardless of page reload ).
How do I access the getters' data inside the method ?
In this case a watch property as follows seems to solve the issue,
watch: {
latLong: {
handler(value) {
if (value.lat && value.long) {
this.getWeather();
}
},
immediate: true,
},
},
I'm using Geolocation in React-Native to receive my current location to load object around me. Below is my code.
getCurrentPosition() {
console.log("checkLocation", "getCurrentPosition1");
navigator.geolocation.getCurrentPosition(
position => {
const { coords } = position;
if (coords !== undefined) {
console.log("checkLocation", "getCurrentPosition trigger");
this.setState({
currentCoordinate: coords,
prevCoorForGet: coords,
prevCoorForUpdate: coords
});
this.props.saveCurrentLocation({
currentLocation: {
latitude: coords.latitude,
longitude: coords.longitude
}
});
this.loadContent(coords);
}
},
error =>
console.log(
"checkLocation",
"getCurrentPosition " + JSON.stringify(error)
),
{
enableHighAccuracy: true,
timeout: 60000,
maximumAge: 3600000
}
);
}
The problem is this code working fine in the first time. But when I navigate to another scene and go back, It isn't work anymore and give me a time out error. Sometime it works, sometime it doesn't. Please help me fix it.
This one is working fine (both ios and android) in my project even working after navigating between pages and return map screen.
navigator.geolocation.getCurrentPosition(
(position) => {
// user location's latitude and longitude
let latitude = parseFloat(position.coords.latitude);
let longitude = parseFloat(position.coords.longitude);
console.log('location position: ', position);
let region = {
latitude: latitude,
longitude: longitude,
latitudeDelta: 0.0522,
longitudeDelta: 0.0321,
};
// to store region data
this.setState({region: region});
//animate to user current location
this.map.animateToRegion(region,1000)
},
(error) => console.log('position error!!!', error),
{enableHighAccuracy: false, timeout: 3000}
);
I hope it works on your project too
Edit
If still not working
/**
* when return the page this listener will trigger
*/
this.props.navigation.addListener('willFocus', (payload) => {
// call location method again
this.getLocation()
});
Try below code, this seems to work for me
import Geolocation from 'react-native-geolocation-service';
componentWillUnmount() {
Geolocation.stopObserving();
}
use your function in componentWillMount() so that every time the component mounts....it function will be executed
I am trying figure out how to listen to event when the user turns on or off the location in the settings. I tried navigator.geolocation.watchposition but didn't have much success, since it does not listen to the respective event.
npm install --save react-native-location
react-native link
var React = require('react-native');
var { DeviceEventEmitter } = React;
var { RNLocation: Location } = require('NativeModules');
Location.getAuthorizationStatus(function(authorization) {
//authorization is a string which is either "authorizedAlways",
//"authorizedWhenInUse", "denied", "notDetermined" or "restricted"
});
Location.requestAlwaysAuthorization();
Location.startUpdatingLocation();
Location.setDistanceFilter(5.0);
var subscription = DeviceEventEmitter.addListener(
'locationUpdated',
(location) => {
/* Example location returned
{
coords: {
speed: -1,
longitude: -0.1337,
latitude: 51.50998,
accuracy: 5,
heading: -1,
altitude: 0,
altitudeAccuracy: -1
},
timestamp: 1446007304457.029
}
*/
}
);
Refer to this site for more details.
You can use https://www.npmjs.com/package/react-native-system-setting
useEffect(() => {
const locationListener = SystemSetting.addLocationListener(
(locationEnabled) => console.log(locationEnabled),
);
return () => SystemSetting.removeListener(locationListener);
}, []);