Reputation: 11
I am relative new to JavaScript.I have a "strange" problem: I have two input fields which when I click the sndBtn (clickEventListener), then 3 functions are called, all with a fetch/get requests and then give a JSON object back.
But when iI click the button, first I get an undefined object, when I click a second time, I get the first object... third the second object etc... so I have to click 3 times and then it works.
Maybe someone can explain how I get it to work on the first click?
Thanks
let vonPlz;
let nachPlz;
let vonOrt;
let nachOrt;
let km;
let kilometer;
let sendBtn;
let vonLon;
let vonLat;
let nachLon;
let nachLat;
let vonJson;
let nachJson;
document.addEventListener('DOMContentLoaded', function(event) {
vonPlz = document.getElementById("vonPlz");
nachPlz = document.getElementById("nachPlz");
vonOrt = document.getElementById("vonOrt");
nachOrt = document.getElementById("nachOrt");
km = document.getElementById("km");
sendBtn = document.getElementById("sendBtn");
sendBtn.addEventListener('click', function() {
getReqVonPlz(vonPlz.value);
getReqNachPlz(nachPlz.value);
console.log(vonJson[0].display_name);
console.log(nachJson[0].display_name);
vonLat = vonJson[0].lat;
vonLon = vonJson[0].lon;
nachLat = nachJson[0].lat;
nachLon = nachJson[0].lon;
postReqKm(vonLat, vonLon, nachLat, nachLon);
console.log(kilometer);
vonOrt.innerHTML = vonJson[0].display_name;
nachOrt.innerHTML = nachJson[0].display_name;
km.innerHTML = kilometer;
})
});
async function getReqVonPlz(plz){
await fetch("https://nominatim.openstreetmap.org/search?format=json&country=de&postalcode=" +plz , {
method: "GET",
headers: {
"Content-type": "application/json; charset=UTF-8"
}
})
.then((response) => response.json())
.then((json) => {vonJson = json});
}
async function getReqNachPlz(plz){
await fetch("https://nominatim.openstreetmap.org/search?format=json&country=de&postalcode=" +plz , {
method: "GET",
headers: {
"Content-type": "application/json; charset=UTF-8"
}
})
.then((response) => response.json())
.then((json) => {nachJson = json});
}
async function postReqKm(vonLat, vonLon, nachLat, nachLon){
await fetch("https://api.openrouteservice.org/v2/directions/driving-car", {
method: "POST",
body: JSON.stringify({
coordinates: [[vonLon,vonLat],[nachLon,nachLat]],
}),
headers: {
"Content-type": "application/json; charset=UTF-8",
"Authorization": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
}
})
.then((response) => response.json())
.then((json) => {kilometer = json.routes[0].summary.distance});
}
first I didn't add the async-await functions? When I tested it with only one function it worked, now I do the async and await on all 3 functions, but I have to click 3 times.
So I think the problem is somewhere with that, but I am really new to that.
Upvotes: 0
Views: 75
Reputation: 542
javascript is async, which means it wont wait for function execution to complete. Hence you need to enforce to make your function synchronised.
Current behaviour of your code:
execute getReqVonPlz w/o waiting
execute getReqNachPlz w/o waiting
execute postReqKm w/o waiting
Desired behaviour :
execute getReqVonPlz and wait
execute getReqNachPlz and wait
execute postReqKm based on the result of above function results
there are several ways you can accomplish this, preferred ones are:
I'll demonstrate the example of await in this answer
var [vonJson, nachJson] = await Promise.all([getReqVonPlz(vonPlz.value), getReqNachPlz(nachPlz.value)]);
vonJson = vonJson.json();
nachJson = nachJson.json();
//process your vonJson & nachJson
var res = await postReqKm(vonLat, vonLon, nachLat, nachLon);
//process your res
make your functions return promise eg.
function getReqNachPlz(plz){
return fetch("https://nominatim.openstreetmap.org/search?format=json&country=de&postalcode=" +plz , {
method: "GET",
headers: {
"Content-type": "application/json; charset=UTF-8"
}
});
}
Upvotes: 1