Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Make a second API call based on first api call response in React with hooks

I am trying to build a weather app with open weather API.
There is a problem with the first call
I have to get the value latitude and longitude from the first API to make a second API call.
I have tried async / await but can’t get the correct structure this code to work
I also tried useEffect hook but failed again.

My code is below. What am I missing?

import React, { useEffect, useState } from 'react';

const api = {
  key: `${process.env.REACT_APP_API_KEY}`,
  base: 'https://api.openweathermap.org/data/2.5/'
}

function App() {

  const [query, setQuery] = useState('');
  const [weather, setWeather] = useState({});
  const [location, setLocation] = useState({ lat: '', lon: '' });
  const [following, setFollowing] = useState([]);




  const search = async (e) => {
    if (e.key === 'Enter') {
      await fetch(`${api.base}weather?q=${query}&units=metric&appid=${api.key}&lang=tr`)
        .then(res => res.json())
        .then(result => {
          setWeather(result);
          setQuery('');
          setLocation(result.coord);
          console.log(result);
          searchFollowing();
        }
        )
    }
  }

    const searchFollowing = async () => {
     await  fetch(`${api.base}onecall?lat=${location.lat}&lon=${location.lon}&units=metric&exclude=hourly,minutely&appid=${api.key}`)
        .then(res => res.json())
        .then(result2 => {
          const array = result2.daily.slice(1, 6);
          console.log(following);
          setFollowing(array);
          // following == array
        }
        )
    }



  const integer = (number) => {
    return Math.floor(Math.round(number));
  }

  const mapped = (following) => {
    following = [...following];
    return following.map((item, idx) => {
      const icon = item.weather[0].icon;
      const day = integer(item.temp.day);
      const night = integer(item.temp.night);
      return (
        <div key={idx} className="box">
          <img
            src={`http://openweathermap.org/img/wn/${icon}.png`}
            alt='weather'
            width={80}
            height={80}
          />
          <h3>Day {day} °C</h3>
          <h3>Night {night} °C</h3>
        </div>
      )
    })
  }

  const dateBuild = (d) => {
    let months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
    let days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']

    let day = days[d.getDay()]
    let date = d.getDate()
    let month = months[d.getMonth()]
    let year = d.getFullYear()

    return `${day} ${date} ${month} ${year}`
  }


  return (
    <div className={(typeof weather.main !== 'undefined') ?
      ((weather.main.temp > 25) ? 'App hot' :
        ((weather.main.temp < 25 && weather.main.temp > 5) ?
          'App warm' : 'App')) : 'App'}>
      <main>
        <div className="search-box">
          <input
            type="text"
            className="search-bar"
            placeholder="Search for a location..."
            onChange={e => setQuery(e.target.value)}
            onKeyPress={search}
            value={query}
          />
        </div>
        {(typeof weather.main != "undefined") ? (
          <div>
            <div className="location-box">
              <div className="location">
                {weather.name}, {weather.sys.country}
              </div>
              <div className="date"> {dateBuild(new Date())}
              </div>
            </div>
            <div className="weather-box">
              <div className="temp">
                {Math.round(weather.main.temp)}°C
                <img
                  src={`http://openweathermap.org/img/wn/${weather.weather[0].icon.slice(0, 2)}d.png`}
                  alt='weather'
                  width={80}
                  height={80}
                />
              </div>
              <div className="weather">
                <p>
                  <span>Hissedilen</span>
                  {Math.floor(weather.main.feels_like)} °C
                </p>
                <p>
                  <span>Ĺžu an</span>
                  {weather.weather[0].description}
                </p>
                <p>
                  <span>Basınç</span>
                  {weather.main.pressure} mb
                </p>
                <p>
                  <span>RĂĽzgar </span>
                  {Math.floor(weather.wind.speed)} km/h
                </p>
                <p>
                  <span>En fazla</span>
                  {Math.floor(weather.main.temp_max)} °C
                </p>
                <p>
                  <span>En az</span>
                  {Math.floor(weather.main.temp_min)} °C
                </p>
              </div>
            </div>
            <div className="followingdays">
              {mapped(following)}
            </div>
          </div>) : ('')}
      </main>
    </div>
  );
}

export default App;

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

What you are missing is that when you are calling searchFollowing(), React did not yet re-render, therefore location wouldn’t be get updated. A way to do it is this :

import React, { useEffect, useState } from 'react';

const api = {
  key: `${process.env.REACT_APP_API_KEY}`,
  base: 'https://api.openweathermap.org/data/2.5/'
}

function App() {

  const [query, setQuery] = useState('');
  const [weather, setWeather] = useState({});
  const [location, setLocation] = useState({ lat: '', lon: '' });
  const [following, setFollowing] = useState([]);


  useEffect(()=>{
  
    if(location.lat && location.lon){
      searchFollowing();
    }
  }, [location])

  const search = (e) => {
    if (e.key === 'Enter') {
      fetch(`${api.base}weather?q=${query}&units=metric&appid=${api.key}&lang=tr`)
        .then(res => res.json())
        .then(result => {
          setWeather(result);
          setQuery('');
          setLocation(result.coord);
        }
        )
    }
  }

    const searchFollowing = () => {
     fetch(`${api.base}onecall?lat=${location.lat}&lon=${location.lon}&units=metric&exclude=hourly,minutely&appid=${api.key}`)
        .then(res => res.json())
        .then(result2 => {
          const array = result2.daily.slice(1, 6);
          console.log(following);
          setFollowing(array);
          // following == array
        }
        )
    }
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading