4

I am working on a little project that involves getting the weather at different locations and also, dynamically getting the time at those locations afterwards. All these worked fine but then i tried to take it a step further by attempting to refresh the data gotten from the API every minute(without resubmitting/pressing the enter key). I've tried various ways of implementing the setinterval function into the code but none seem to work. Here is what the code looks like:

function App() {
    const [query, setQuery] = useState("");
    const [weather, setWeather] = useState({});
    const [timeZone, setTimeZone] = useState({});

    const handleChange = (e) => {
        setQuery(e.target.value);
    };
    const apiCall = () => {
        Axios({
            method: "get",
            url: `${api.timeBase}apiKey=${api.timeKey}&location=${query}`,
            timeout: 10000, 
        })
            .then((res) => {
                console.log(res.data);
                setWeather(res.data);
                //setQuery("");
            })
            .catch((err) => {
                console.log(err);
            });
    };

    const handleSubmit = (e) => {
        e.preventDefault();
        apiCall();
    };
    useEffect(() => {
        setInterval(apiCall, 60000);
    }, []);

    useEffect(() => {
        if (weather.main !== undefined) {
            Axios.get(
                `${api.timeBase}apiKey=${api.timeKey}&location=${weather.name}, ${weather.sys.country}`
            )
                .then((res) => {
                    console.log(res.data);
                    setTimeZone(res.data);
                })
                .catch((err) => {
                    console.log(err);
                });
        }
    }, [weather]);

Basically, the issue i get the most is that somewhere within the setinterval function, the queryparameter is cleared and the API continues to retrieve a different location till gets back to normal. i tried preventing the query parameter from clearing after it updates the state, that didnt help.

PS: i had to breakdown the handlesubmit because attaching the setinterval to the original block of code throws an error cause e.preventDefault isn't defined. Also, I think calling the setInterval without the useEffect makes things a lot worse too.

1
  • I think it should refresh data because useEffect is calling apiCall function every one minute accurately.There must be some other problem Commented Oct 15, 2020 at 4:25

1 Answer 1

2

Clear out the interval after the interval is finished. The setInterval function returns a timerId that should be cleared out otherwise, it remains in the timer pool and can execute even after the instance of the callback has been run.

React.useEffect(() => {
   const id = setInterval(apiCall, 60000);
   return () => clearInterval(id);
}, []);
Sign up to request clarification or add additional context in comments.

1 Comment

i think i actually just solved it now. i passed in the query as a dependency to the useEffect that bears the setInterval. everything seems to be working as expected. whew!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.