skip to Main Content
const searchbtn = document.getElementById('Search-btn');
const cityinput = document.getElementById('city-input');
const apiKey = 'key';
let lon;
let lat;

function GeoGet() {
    let GeoApiUrl = `http://api.openweathermap.org/geo/1.0/direct?q=${cityinput.value}&limit=1&appid=${apiKey}`
    fetch(GeoApiUrl)
        .then(response => response.json())
        .then(data => {
           lon = data[0].lon;
            lat = data[0].lat;
            console.log(lon)
            console.log(lat)
        })
        .catch(error => {
            console.error();
        });
}
searchbtn.onclick = () => {
    GeoGet();
    console.log(lon);
    console.log(lon);
}

I want to change the lon and lat in the function, but it does not work.
I can’t understand why

Console

3

Answers


  1. The problem is that you console log the variables before they were changed. This is because the code runs in sync and it does not wait for the response.

    Try this:

    searchbtn.onclick = async () => {
        await GeoGet();
        console.log(lon);
        console.log(lon);
    }
    
    Login or Signup to reply.
  2. The problem is that you are using a fetch call, which is a Promise, but are not waiting for the then callback to be finished before executing the console.log in your onclick. You’ll either need to make GetGet an async function and call it via await in onclick (making that async too), or place the console.logs inside the then callback. The latter is preferable, as await calls are blocking.

    Blocking With async/await

    const searchbtn = document.getElementById('Search-btn');
    const cityinput = document.getElementById('city-input');
    const apiKey = 'key';
    let lon;
    let lat;
    
    const GeoGet = async () => {
        let GeoApiUrl = `http://api.openweathermap.org/geo/1.0/direct?q=${cityinput.value}&limit=1&appid=${apiKey}`
        try {
            const response = await fetch(GeoApiUrl);
            const json = await response.json(); // await may not be necessary here
            lon = json[0].lon;
            lat = json[0].lat;
        } catch (err) {
            console.error(err.message);
        }
        return { lon, lat };
    };
    searchbtn.onclick = async () => {
        await GeoGet();
        console.log(lon);
        console.log(lat);
    }
    

    Non-Blocking With Moving console.logs

    const searchbtn = document.getElementById('Search-btn');
    const cityinput = document.getElementById('city-input');
    const apiKey = 'key';
    let lon;
    let lat;
    
    function GeoGet() {
        let GeoApiUrl = `http://api.openweathermap.org/geo/1.0/direct?q=${cityinput.value}&limit=1&appid=${apiKey}`
        fetch(GeoApiUrl)
            .then(response => response.json())
            .then(data => {
                lon = data[0].lon;
                lat = data[0].lat;
                console.log(lon)
                console.log(lat)
            })
            .catch(error => {
                console.error();
            });
    }
    searchbtn.onclick = () => {
        GeoGet();
    }
    
    Login or Signup to reply.
  3. As discussed in comment and some guys explained in other posts about
    fetch,
    So here’s solution using async&await:

    let lon;
    let lat;
    async function GeoGet() {
      let GeoApiUrl = `http://api.openweathermap.org/geo/1.0/direct?q=${cityinput.value}&limit=1&appid=${apiKey}`;
      let response = await fetch(GeoApiUrl);
      let data = await response.json();
      lat = data[0].lat;
      lon = data[0].lon;
    }
    searchbtn.onclick = async () => {
      await GeoGet();
      console.log(lon);
      console.log(lon);
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search