I am facing an error regarding Geocoding API.
I am trying to get the coordinates when the user presses this button
<TouchableOpacity
style={tw`flex-row items-center p-5`}
onPress={() => {
dispatch(
setDestination({
geometry: {
location: { lat: 3.0023237, lng: 101.7059165 },
},
description,
}),
);
}}
>
Here is the full code of Map.js:
import { StyleSheet, Text, View } from 'react-native';
import React, { useEffect, useRef, useState } from 'react';
import MapView, { Marker } from 'react-native-maps';
import tw from 'twrnc';
import { useDispatch, useSelector } from 'react-redux';
import {
selectDestination,
selectOrigin,
setDestination,
setTravelTimeInformation,
setMarker,
} from '../slices/navSlice';
import MapViewDirections from 'react-native-maps-directions';
import { GOOGLE_MAPS_APIKEY } from '@env';
const Map = () => {
const origin = useSelector(selectOrigin);
const destination = useSelector(selectDestination);
const mapRef = useRef(null);
const dispatch = useDispatch();
useEffect(() => {
if (!origin || !destination) return;
mapRef.current.fitToSuppliedMarkers(['origin', 'destination'], {
edgePadding: { top: 50, right: 50, bottom: 50, left: 50 },
});
}, [origin, destination]);
useEffect(() => {
if (!origin || !destination) return;
const getTravelTime = async () => {
fetch(
`https://maps.googleapis.com/maps/api/distancematrix/json?destinations=${destination.description}&origins=${origin.description}&units=imperial&key=${GOOGLE_MAPS_APIKEY}`,
)
.then((res) => res.json())
.then((data) => {
dispatch(setTravelTimeInformation(data.rows[0].elements[0]));
});
};
getTravelTime();
}, [origin, destination, GOOGLE_MAPS_APIKEY]);
useEffect(() => {
if (!origin || !destination) return;
const getCoordinates = async () => {
fetch(
`https://maps.googleapis.com/maps/api/geocode/json?address=${destination.description}&key=${GOOGLE_MAPS_APIKEY}`,
)
.then((res) => res.json())
.then((data) => {
dispatch(setDestination(data.results[0].geometry.location));
});
};
getCoordinates();
}, [destination, GOOGLE_MAPS_APIKEY]);
return (
<MapView
ref={mapRef}
showsUserLocation
style={tw`flex-1`}
mapType="mutedStandard"
initialRegion={{
latitude: origin.location.lat,
longitude: origin.location.lng,
latitudeDelta: 0.005,
longitudeDelta: 0.005,
}}
>
{origin && destination && (
<MapViewDirections
origin={origin.description}
destination={destination.description}
apikey={GOOGLE_MAPS_APIKEY}
strokeWidth={3}
strokeColor="blue"
/>
)}
{origin?.location && (
<Marker
pinColor={'green'}
coordinate={{
latitude: origin.location.lat,
longitude: origin.location.lng,
}}
title="Origin"
description={origin.description}
identifier="origin"
/>
)}
{destination?.location && (
<Marker
coordinate={{
latitude: destination.location.lat,
longitude: destination.location.lng,
}}
title="Destination"
description={destination.description}
identifier="destination"
/>
)}
</MapView>
);
};
export default Map;
The exact part that causes the error is this:
useEffect(() => {
if (!origin || !destination) return;
const getCoordinates = async () => {
fetch(
`https://maps.googleapis.com/maps/api/geocode/json?address=${destination.description}&key=${GOOGLE_MAPS_APIKEY}`,
)
.then((res) => res.json())
.then((data) => {
dispatch(setDestination(data.results[0].geometry.location));
});
};
getCoordinates();
}, [destination, GOOGLE_MAPS_APIKEY]);
it comes from this:
.then((data) => {
dispatch(setDestination(data.results[0].geometry.location));
});
The error:
[Unhandled promise rejection: TypeError: undefined is not an object (evaluating 'data.results[0].geometry')]
at node_modules\promise\setimmediate\core.js:null in tryCallOne
at node_modules\promise\setimmediate\core.js:null in setImmediate$argument_0
at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:null in _allocateCallback$argument_0
at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:null in _callTimer
at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:null in _callReactNativeMicrotasksPass
at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:null in callReactNativeMicrotasks
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:null in __callReactNativeMicrotasks
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:null in __guard$argument_0
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:null in __guard
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:null in flushedQueue
the reducer js file: NavSlice.js
import { createSlice } from '@reduxjs/toolkit';
const initialState = {
origin: null,
destination: null,
travelTimeInformation: null,
marker: {},
};
export const navSlice = createSlice({
name: 'nav',
initialState,
reducers: {
setOrigin: (state, action) => {
state.origin = action.payload;
},
setDestination: (state, action) => {
state.destination = action.payload;
},
setTravelTimeInformation: (state, action) => {
state.travelTimeInformation = action.payload;
},
},
});
export const { setOrigin, setDestination, setTravelTimeInformation } = navSlice.actions;
export const selectOrigin = (state) => state.nav.origin;
export const selectDestination = (state) => state.nav.destination;
export const selectTravelTimeInformation = (state) => state.nav.travelTimeInformation;
export default navSlice.reducer;
store.js
import { configureStore } from '@reduxjs/toolkit';
import navReducer from './slices/navSlice.js';
export const store = configureStore({
reducer: {
nav: navReducer,
},
});
I am not very sure on why this is not working, any ideas? This should work similarly to when you set the destination to your favorite location. Like Uber.
CodePudding user response:
fixed!!
useEffect(() => {
if (!origin || !destination) return;
const getCoordinates = async () => {
fetch(
`https://maps.googleapis.com/maps/api/geocode/json?address=${destination.description}&key=${GOOGLE_MAPS_APIKEY}`,
)
.then((res) => res.json())
.then((data) => {
if(data && data.results && data.results[0] && data.results[0].geometry){
dispatch(setDestination({...destination, location: data.results[0].geometry.location}));
}
});
};
getCoordinates();
}, [destination, GOOGLE_MAPS_APIKEY]);
CodePudding user response:
It's a simple error of undefined, which means object you are trying to access is not an object
console.log(data)
before this line and check whether data is an object or undefined and then check if there is an array of results in data object.
dispatch(setDestination(data.results[0].geometry.location));