skip to Main Content

New to programming in React. Using api axios i’ve retrieved weather information. What i’m trying to do is if a user select a specific city from the drop down list i want the weather information for that city to be shown – to be honest i’ve researched but not sure how to go about code.
Is there anyone can direct me. At the moment if i hard code a city i get weather on the api url i get the information but i want users to be able to choose any location from the drop down list specified.
My code so far:

import React, { useEffect } from "react";
import axios from "axios";
import "./App.css";

import { useState } from "react";

function App({ searchCities }) {
  const [city, setCity] = useState([]);
  const [isLoading, setIsLoading] = useState(true);


  const url = `https://api.openweathermap.org/data/2.5/weather?q=${searchCities}&units=metric&appid=08acd577f8ab8cabf637f7cd3736a629`;

  useEffect(() => {
    axios.get(url).then((response) => {
      setCity(response.data);
      console.log(response.data);
      setIsLoading(false);
    });
  }, [searchCities]);

  const [newSearchTerm, setNewSearchTerm] = useState('');

  const handleChange = (event) =>{
    setNewSearchTerm(event.target.value);
    
  }

  const handleSubmit = (event) => {
      event.preventDefault();
      searchCities(newSearchTerm);
      setNewSearchTerm('');
  }

  if (isLoading) {
    return <h2>Still Loading be patient</h2>;
  }
  
  return (
    <form onSubmit={handleSubmit}>
    <div>
      <div>
        <ul>
          <select name="city">
            <option value="0">Choose the City</option>
            <option value="Dallas">Dallas</option>
            <option value="London">London</option>
          </select>
          <h3>Humidity: {city.main.humidity}</h3>
          <h3>Temp: {city.main.temp}</h3>
        </ul>
      </div>
    </div>
    </form>
  );
}

export default App;

2

Answers


  1. Try this

    import React, { useEffect } from "react";
    import axios from "axios";
    
    import { useState } from "react";
    
    function App({ searchCities }) {
      const [city, setCity] = useState(null);
      const [weatherData, setWeatherData] = useState(null);
      const [isLoading, setIsLoading] = useState(false);
    
      const getWeatherData = (selectedCity) => {
        if (selectedCity) {
          const url = `https://api.openweathermap.org/data/2.5/weather?q=${selectedCity}&units=metric&appid=08acd577f8ab8cabf637f7cd3736a629`;
          axios.get(url).then((response) => {
            setWeatherData(response.data);
            console.log(response.data);
            setIsLoading(false);
          });
        }
      };
      useEffect(() => {}, [searchCities]);
    
      const [newSearchTerm, setNewSearchTerm] = useState("");
    
      const handleChange = (event) => {
        console.log(event.target.value);
        setCity(event.target.value);
      };
      useEffect(() => {
        if (city) {
          setIsLoading(true);
          getWeatherData(city);
        }
      }, [city]);
      const handleSubmit = (event) => {
        /* event.preventDefault();
          searchCities(newSearchTerm);
          setNewSearchTerm(''); */
      };
    
      if (isLoading) {
        return <h2>Still Loading be patient</h2>;
      }
    
      return (
        <form onSubmit={handleSubmit}>
          <div>
            <div>
              <ul>
                <select name="city" onChange={handleChange}>
                  <option value="0">Choose the City</option>
                  <option value="Dallas">Dallas</option>
                  <option value="London">London</option>
                </select>
                <h3>Humidity: {weatherData?.main.humidity}</h3>
                <h3>Temp: {weatherData?.main.temp}</h3>
              </ul>
            </div>
          </div>
        </form>
      );
    }
    
    export default App;
    
    Login or Signup to reply.
  2. You should have an onChange prop to the select element and pass it a handler function that would update the city state, the handler function would be:

    const handleCityChange = (e) => {
      setSelectedCity(e.target.value);
      // ...
    };
    

    Another thing I would suggest you is instead of using a selectable option "Choose the City" you can make it the "default" option by setting the initial value of city value to be "default" and the first option would have this value="default" and pass it a disabled prop to make it unselectable:

    // ...
    const [selectedCity, setSelectedCity] = useState("default");
    // ...
    <select name="city" value={selectedCity} onChange={handleCityChange}>
      <option value="default" disabled>Choose the City</option>
    // ...
    

    EDIT2: I noticed you are using setCity for the data received, so I have created another selectedCity state.

    The final code would look like this:

    import React, { useEffect } from "react";
    import axios from "axios";
    import "./App.css";
    
    import { useState } from "react";
    
    function App({ searchCities }) {
      const [city, setCity] = useState([]);
      const [isLoading, setIsLoading] = useState(true);
      const [selectedCity, setSelectedCity] = useState("default");
    
    
      const url = `https://api.openweathermap.org/data/2.5/weather?q=${searchCities}&units=metric&appid=08acd577f8ab8cabf637f7cd3736a629`;
    
      useEffect(() => {
        axios.get(url).then((response) => {
          setCity(response.data);
          console.log(response.data);
          setIsLoading(false);
        });
      }, [searchCities]);
    
      const [newSearchTerm, setNewSearchTerm] = useState('');
    
      const handleChange = (event) =>{
        setNewSearchTerm(event.target.value);
        
      }
    
      const handleSubmit = (event) => {
          event.preventDefault();
          searchCities(newSearchTerm);
          setNewSearchTerm('');
      }
    
      if (isLoading) {
        return <h2>Still Loading be patient</h2>;
      }
    
    // Define handleCityChange function
      const handleCityChange = (e) => {
        setSelectedCity(e.target.value);
     
        // Make HTTP request when city is changed
        axios.get(`https://api.openweathermap.org/data/2.5/weather?q=${e.target.value}&units=metric&appid=08acd577f8ab8cabf637f7cd3736a629`)
        .then((response) => {
          setCity(response.data);
          console.log(response.data);
          setIsLoading(false);
        });
      };
      
      return (
        <form onSubmit={handleSubmit}>
        <div>
          <div>
            <ul>
              <select name="city" value={selectedCity} onChange={handleCityChange}>
                <option value="default" disabled>Choose the City</option>
                <option value="Dallas">Dallas</option>
                <option value="London">London</option>
              </select>
              <h3>Humidity: {city.main.humidity}</h3>
              <h3>Temp: {city.main.temp}</h3>
            </ul>
          </div>
        </div>
        </form>
      );
    }
    
    export default App;
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search