I think I am missunderstanding how the async await is working, especially with a function from another file. So I want to get an adress from longitude and latitude using an axios call on an API
import { getAddressFromLongLat } from "../hooks/queries-hook";
import React, { useEffect, useState } from "react";
const Component = (props) => {
const [address, setAddress] = useState(null);
useEffect(() => {
const fetchFromLongLat = async () => {
if (props.coords) {
const response = await getAddressFromLongLat(props.coords);
console.log("response from nominatim " JSON.stringify(response, null, 4));
setAddress(response);
}
};
fetchFromLongLat();
}, []);
return <></>;
};
then into queries-hook.js
import axios from "axios";
export const getAddressFromLongLat = async (coords) => {
const URL = "http://nominatim.openstreetmap.org/reverse";
const response = await axios.get(URL, {
params: {
format: "json",
lat: coords.lat,
lon: coords.long
},
headers: {
"Content-Type": "application/json; charset=UTF-8"
}
});
return {
street: response.address.road " " response.address.house_number,
cp: response.address.postcode,
city: response.address.town,
country: response.address.country_code.toUpperCase()
};
};
can someone explain me how I should write correctly the code with those async await to not have the error:
Possible Unhandled Promise Rejection (id: 0): TypeError: undefined is not an object (evaluating 'response.address.road')
CodePudding user response:
Issue is due to response
does not contains address
property and all the rest. But response.data
do.
You had to add a console.log(response);
before return
to figure that out. The output for { "lat": 50.806002951249546, "long": 4.410705976188183 }
will be this:
{
"data": {
"place_id": 113461740,
"licence": "Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright",
"osm_type": "way",
"osm_id": 30994925,
"lat": "50.8066154",
"lon": "4.410838323013642",
"display_name": "Parc sportif des Trois Tilleuls, Avenue Léopold Wiener - Léopold Wienerlaan, Le Triangle - De Driehoek, Ватермаль-Буафор, Брюссельский столичный регион, 1170, Бельгия",
"address": {
"leisure": "Parc sportif des Trois Tilleuls",
"road": "Avenue Léopold Wiener - Léopold Wienerlaan",
"neighbourhood": "Le Triangle - De Driehoek",
"town": "Ватермаль-Буафор",
"county": "Брюссельский столичный регион",
"region": "Брюссельский столичный регион",
"ISO3166-2-lvl4": "BE-BRU",
"postcode": "1170",
"country": "Бельгия",
"country_code": "be"
},
"boundingbox": [
"50.8042107",
"50.80902",
"4.4079878",
"4.4130556"
]
},
"status": 200,
"statusText": "",
...
(cutted)
}
So fixed function:
const getAddressFromLongLat = async (coords) => {
// switched to HTTPS here also
const URL = "https://nominatim.openstreetmap.org/reverse";
const response = await axios.get(URL, {
params: {
format: "json",
lat: coords.lat,
lon: coords.long
},
headers: {
"Content-Type": "application/json; charset=UTF-8"
}
});
const { data } = response; // equal to const data = response.data
return {
street: data.address.road " " data.address.house_number,
cp: data.address.postcode,
city: data.address.town,
country: data.address.country_code.toUpperCase()
};
};
CodePudding user response:
import axios from 'axios';
import React from 'react'
import { useEffect } from 'react';
import { useState } from 'react';
const Try = () => {
const [address, setAddress] = useState(null);
const getAddressFromLongLat = async () => {
const URL = "http://nominatim.openstreetmap.org/reverse";
const response = await axios.get(URL, {
params: {
format: "json",
lat: 36.884804,
lon: 30.704044
},
headers: {
"Content-Type": "application/json; charset=UTF-8"
}
});
const { data } = response; **// There is your mistake.**
return {
street: data.address.road " " data.address.house_number,
cp: data.address.postcode,
city: data.address.town,
country: data.address.country_code.toUpperCase()
};
};
useEffect(() => {
const fetchFromLongLat = async () => {
if (1 === 1) {
const response = await getAddressFromLongLat();
console.log("response from nominatim " JSON.stringify(response, null, 4));
setAddress(response);
}
};
fetchFromLongLat();
}, []);
console.log(address)
return (
<div>try</div>
)
}
export default Try
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.27.2/axios.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
CodePudding user response:
I'm not sure, but may be you don't need use async...await in second function. This is like tako inside tako. But you need just two tako in one tako bell.