Home > Blockchain >  the UI updates only at the second click
the UI updates only at the second click

Time:04-30

I need to create an asynchronous web app that uses vanilla JS , Web API(OpenWeather API) and and user data to dynamically update the UI. it's fast done, except one problem: the UI updates only at the second click of to generate Btn, I don't know where the bug could be? plz help me.

Project screencut

const d = new Date();
const newDate = d.toDateString();

const baseURL =
  "http://api.openweathermap.org/data/2.5/weather?units=imperial&zip=";
const apiKey = "&appid=b0c6dd1560b603095aed754d5d1756d0&units=imperial";


document.getElementById("generate").addEventListener("click", performAction);


function performAction(e) {
  const feelings = document.getElementById("feelings").value;
  const newZip = document.getElementById("zip").value;

  getWeather(baseURL, newZip, apiKey)
    .then(function (data) {
      postData("/addData", {
        name: data.name,
        date: newDate,
        temp: data.main.temp,
        feelings: feelings
      });
    })
    .then(updateUI());
}


const getWeather = async (baseURL, newZip, apiKey) => {
  const request = await fetch(baseURL   newZip   apiKey);

  try {
    const allData = await request.json();


    if (allData.message) {
      alert(allData.message);
    } else {
      return allData;
    }
  } catch (error) {
    console.log("error", error);
  }
};



const postData = async (url = "", data = {}) => {
  const res = await fetch(url, {
    method: "POST",
    credentials: "same-origin",
    headers: {
      "Content-Type": "application/json"
    },
    body: JSON.stringify(data)
  });

  try {
    const newData = await res.json();
    return newData;
  } catch (error) {
    console.log("error", error);
  }
};


const updateUI = async () => {
  const req = await fetch("/all");
  try {
 
    const allData = await req.json();
    document.getElementById("name").innerHTML = allData.name;
    document.getElementById("date").innerHTML = allData.date;
    document.getElementById("temp").innerHTML =
      Math.round(allData.temp)   " degrees fahrenheit";
    document.getElementById("content").innerHTML = "I am feeling " allData.feelings;
  } catch (error) {
    console.log("error", error);
  }
};

CodePudding user response:

Add then directly to postData:

postData("/addData", {
        name: data.name,
        date: newDate,
        temp: data.main.temp,
        feelings: feelings
      }).then(updateUI);

Or add return

getWeather(baseURL, newZip, apiKey)
    .then(function (data) {
      return postData("/addData", {
        name: data.name,
        date: newDate,
        temp: data.main.temp,
        feelings: feelings
      });
    })
    .then(updateUI);

CodePudding user response:

The problems are in the performAction function:

function performAction(e) {
  const feelings = document.getElementById("feelings").value;
  const newZip = document.getElementById("zip").value;

  getWeather(baseURL, newZip, apiKey)
    .then(function (data) {
      postData("/addData", {
        name: data.name,
        date: newDate,
        temp: data.main.temp,
        feelings: feelings
      });
    })
    .then(updateUI());
}

Once getWeather resolves, the callback passed to then just calls postData and returns undefined causing the second then's callback to execute early.

Just add a return keyword before postData and update the second then block from then(updateUI()) to then(updateUI) or then(() => updateUI()).

function performAction(e) {
  const feelings = document.getElementById("feelings").value;
  const newZip = document.getElementById("zip").value;

  getWeather(baseURL, newZip, apiKey)
    .then(function (data) {
      return postData("/addData", {
        name: data.name,
        date: newDate,
        temp: data.main.temp,
        feelings: feelings
      });
    })
    .then(() => updateUI()); 
}
  • Related