Lenrok5
Lenrok5

Reputation: 13

React hooks - fetching data from api and passing to a component

So basically, I'm trying to fetch data from api and pass it to Component.

I create usePosition hook to get my positon from browser, and then get response from api. I really don't know how to wait with useEffect for my position, when i'm executing this code now I'm getting always log 'no position'.

const usePosition = () => {
    const [error, setError] = useState(null);
  const [position, setPosition] = useState();

  useEffect(() => {
    const geo = navigator.geolocation;
        if(!geo) {
            setError('Geolocation is not supported.');
            return;
        }

        const handleSuccess = position => {
            const { latitude, longitude } = position.coords;
            setPosition({
                latitude,
                longitude
            });
        };

        const handleError = error => {
            setError(error.message);
        };

        geo.getCurrentPosition(handleSuccess, handleError);

    }, []);

    return { position, error };
}


function App() {
  const {position, error} = usePositon();
  const [weather, setWeather] = useState([]);

  useEffect(() => {
    if(position) {
      const URL = `https://api.openweathermap.org/data/2.5/onecall?lat=${position.latitude}&lon=${position.longitude}&exclude=current,minutely,daily&units=metric&lang=pl&appid=${API_KEY}`;

      const fetchData = async () => {
        const result = await fetch(URL)
          .then(res => res.json())
          .then(data => data);
        setWeather(result.hourly);  
      }
      fetchData();
    } else {
      console.log('no position');
    }
  }, []);

  return (
      <div className="App">
        <div>
          <Swiper weather={weather}/>
        </div>
      </div>
    )
}

Upvotes: 1

Views: 796

Answers (1)

skyboyer
skyboyer

Reputation: 23763

It's all because of [] empty dependencies list down in App's useEffect. It runs exactly once on mount, when usePosition has not requested anything yet. And once it successes later and returns different { error, position } App does not react.

How to solve? Provide things as dependencies:

useEffect(() => {
    if(position) {
      const URL = `https://api.openweathermap.org/data/2.5/onecall?lat=${position.latitude}&lon=${position.longitude}&exclude=current,minutely,daily&units=metric&lang=pl&appid=${API_KEY}`;

      const fetchData = async () => {
        const result = await fetch(URL)
          .then(res => res.json())
          .then(data => data);
        setWeather(result.hourly);  
      }
      fetchData();
    } else {
      console.log('no position');
    }
  }, [position, error]);

Upvotes: 1

Related Questions