JavasScript fetch/get Request / 2 times / 3 times click button

65 views Asked by At

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.

1

There are 1 answers

1
Pranay Nailwal On

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:

  1. Promises Chaining
  2. Using awaits or await-all

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"
    }
    });

}