I currently have an asynchornous function that fetches from https://www.overpass-api.de/api/interpreter? and prints exactly what I need:
async function callRelation(id) {
const api = await fetch("https://www.overpass-api.de/api/interpreter?", {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: "[out:json];rel(" id ");(._;>;);out;",
});
const request = await api.json();
let path = [];
for (let pair of request.elements) {
if (pair.type === "node") {
path.push([pair.lat, pair.lon]);
}
}
return path;
}
async function retreive() {
let test1 = await callRelation(10000); //exmaple relationid btw
console.log(test1);
return test1;
}
It outputs a set of coordinates using an array of [.lat,.lon]
. I'm trying to utilise <Polyline>
but unusually it's not showing anything on the leaflet:
export default function Map() {
return (
<MapContainer center={[51.505, -0.09]} zoom={13} scrollWheelZoom={true}>
<TileLayer
href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<Polyline pathOptions={limeOptions} positions={test} />
</MapContainer>
);
}
My previous attempts used to break leaflet because the async array would output with undefined
in the console, but i've fixed it now which means it's another issue. However, Polyline is not outputting anything, and it works when I enter a simple test constant like:
const test = [
[1, 2],
[3, 1],
];
How can I approach this problem?
CodePudding user response:
You do not show how you populate the test
variable that is supposed to contain the array of coordinate pairs.
There is a high chance you populate it from outside your Map
React function component, which would be the cause of React not re-rendering once you receive your asynchronous result, because React would not be aware of that change.
The solution is to have test
as a state (with useState
hook), then to perform the async result assignment within the component function body, typically through useEffect
hook:
export default function Map() {
// test placeholder as a React state
const [test, setTest] = React.useState([]);
// Call data fetch once on component creation
React.useEffect(() => {
retreive().then((test1) => {
// When data is received, assign it to the state,
// so that React is aware of the change
// and re-renders the component with updated data
setTest(test1);
});
}, []);
return (
<MapContainer center={[51.505, -0.09]} zoom={13} scrollWheelZoom={true}>
<TileLayer
href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<Polyline pathOptions={limeOptions} positions={test} />
</MapContainer>
);
}