1

Making a weather app and I'm trying to update my api call on submit from a form. This is my first shot at making my own program and I've hit a block. I'm setting my API call from useState, and the idea is the user types in the city, hits the button, and the API call runs again and displays the new data from the city. I'm new to thinking as a programmer so I'm almost certain I'm missing something very simple.

import React, { useState, useEffect } from 'react';
import {Card} from 'react-bootstrap';
import Aux from '../../hoc/Aux';
// import classes from './wCard.css';
// import {Button} from 'react-bootstrap';


function WCard () {
        const [city,setCity] = useState('Queens');
        // const key = 'APP_KEY';
        const [feels_like,setFeelsLike] = useState('');
        const [mainTemp,setMainTemp] = useState('');
        const [description,setDescription] = useState('');
        const [main,setMain] = useState('');
        const [iconID,setIconID] = useState('');
        
        // useEffect(() => {
            


        const handleChange = (event) => {
            event.preventDefault()
            setCity(event.target.value)
        }

        const handleSubmit = (event) => {
            event.preventDefault()
            setCity(document.getElementsByName("city")[0].value)
            fetch(
                'https://api.openweathermap.org/data/2.5/weather?q=' + (city) + '&appid&units=imperial'
            )
                .then((res) => res.json())
                .then((data) => {
                    console.log(data);
                    setFeelsLike(data.main.feels_like);
                    setMainTemp(data.main.temp);
                    setDescription(data.weather[0].description);
                    setMain(data.weather[0].main);
                    setIconID(data.weather[0].icon);
                })
        },[city])
        
        
       
    return (
        <Aux>
            <div>
                <label>City</label>
                <form onSubmit={handleSubmit} >
                    <input type="text" placeholder="Ayyy" onChange={handleChange} />
                    <button type="submit">Weather time</button>
                </form>
            </div>

        <div style={{ display:'flex', justifyContent:'center', padding:'5em' }} >
            <Card style={{ width: '24rem', marginTop: '-3em' }}>
                <Card.Img variant="top" src={"http://openweathermap.org/img/wn/" + iconID + "@2x.png"} />
                <h1 style={{ textAlign:'center', color:'#00BFFF' }} >{city}</h1>
                <Card.Body>
                    <Card.Title>{mainTemp}°, feels like {feels_like}°</Card.Title>
                    <Card.Text style={{ textTransform:'capitalize' }} >
                    {description}
                    </Card.Text>
                </Card.Body>
            </Card>
            </div>
        </Aux>
    )    
}

export default WCard;
1
  • Try matching the expected value of the state when you first initialise it on creation, for example, if mainTemp you expect to be a number then const [mainTemp,setMainTemp] = useState(0); Commented Oct 20, 2020 at 17:39

3 Answers 3

1

I believe your useEffect isn't being called again, since you passed in a [] as your array of dependencies. Try doing useEffect(..., [city]). That way, useEffect will be called on update of city

Sign up to request clarification or add additional context in comments.

13 Comments

I think that worked but now a new issue: I get thrown an error as I start typing in the form. I believe it's because it updates the api call immediately so on my first keystroke I get an error. Any idea how I could wait til I hit the button to update?
Are you still using that handleChange function? I don't see it in the code, but I see that you declare it. That's probably what's catching every keystroke- just delete that?
Yeah I'm not actually using it at all. I have something new though: on submit I am now making another API call but it is being shown as 'undefined'. I must be messing up my handle submit somehow.
Could you copy and paste what you have now?
Not in these comments, but I'm almost certain this has something to do with the <input> and my handleSubmit, I'm not targeting the input correctly
|
0

in

const handleSubmit = (event) => {
            event.preventDefault()
            setCity(event.target.value.city)
            
        }

There is a typo. It should be event.target.value not event.target.value.city

And there is no need to have the onChange method.

And as you now know from what Victor said, useEffect will get called if the given dependency changes.

1 Comment

Yeah got rid of the onChange handler, but even with that change the console is saying:wCard.js:17 GET api.openweathermap.org/data/2.5/… 400 (Bad Request), so it's still showing the part i pass in from the state as undefined.
0

use this on useEffect

useEffect(..., [city])

and in handleSubmit there is the problem that event.target is where the click has been triggered, so in this case, the button, you must target the input

const handleSubmit = (event) => {
        event.preventDefault()
        setCity(document.getElementsByName("city")[0].value)
    }

the rest of the code is ok

5 Comments

Did that and the console is showing that city is being plugged into the api call as 'undefined'.
that is related to the reading, of event.target.value
Yeah exactly, no idea why though
take a look at the edit and let me know if it works and if you understand the issue
in the answer itself, I changed the handleSubmit

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.