Home > front end >  Getting an error in react using openweather API "TypeError: Cannot read properties of undefined
Getting an error in react using openweather API "TypeError: Cannot read properties of undefined

Time:09-23

HERE IS THE REACT CODE

import React, { useEffect, useState } from "react";
import "./css/style.css";
import { BiStreetView } from "react-icons/bi";

const Tempapp = () => {
  const [city, setCity] = useState(null);
  const [search, setSearch] = useState("");

  useEffect(() => {
    try {
      const fetchApi = async () => {
        const url = `https://api.openweathermap.org/data/2.5/weather?q=${search}&units=metric&appid=83ea3057047027c6c4521d32d69250a0`;
        const res = await fetch(url);
        const resjson = await res.json();
        
        setCity(resjson);
      };
      fetchApi();
    } catch (error) {
      console.log(error);
    }
  }, [search]);

  return (
    <>
      <div className="box">
        <div className="inputData">
          <input
            type="search"
            className="inputFeild"
            value={search}
            placeholder="Enter city"
            onChange={(event) => {
              setSearch(event.target.value);
            }}
          />
        </div>
        {!city ? (
          <p>Enter city or country to know weather</p>
        ) : (
          <div>
            <div className="info">
              <img
                src="../images/weather.png"
                alt="image"
                className="info-img"
              />

              <h3 className="dateTime">{date}</h3>
              <h3 className="dateTime">{time}</h3>
              <h2 className="location">
                <BiStreetView className="location-icon" />
                {search}
              </h2>
              <h1 className="temp">{city.main.temp} °Cel</h1>

              <h3 className="tempmin_max">
                Min : {city.main.temp_min} °Cel | Max : {city.main.temp_max} °Cel
              </h3>
            </div>
            <div className="wave -one"></div>
            <div className="wave -two"></div>
            <div className="wave -three"></div>
          </div>
        )}
      </div>
    </>
  );
};

export default Tempapp;

AND HERE IS THE API DATA. AND I WANT TO USE THE MAIN PART AND WEATHER PART OF DATA.

and I want to get the temperature, temp_min, temp_max from main object and main from the weather array. I am getting error called cannot read property of undefined reading "temp". please someone solve this.

{
  "coord": {
    "lon": 73.8333,
    "lat": 15.4833
  },
  "weather": [{
    "id": 804,
    "main": "Clouds",
    "description": "overcast clouds",
    "icon": "04n"
  }],
  "base": "stations",
  "main": {
    "temp": 298.95,
    "feels_like": 299.75,
    "temp_min": 298.95,
    "temp_max": 298.95,
    "pressure": 1011,
    "humidity": 83,
    "sea_level": 1011,
    "grnd_level": 1011
  },
  "visibility": 10000,
  "wind": {
    "speed": 2.94,
    "deg": 303,
    "gust": 4.1
  },
  "clouds": {
    "all": 86
  },
  "dt": 1663596174,
  "sys": {
    "country": "IN",
    "sunrise": 1663548808,
    "sunset": 1663592632
  },
  "timezone": 19800,
  "id": 1260607,
  "name": "Panjim",
  "cod": 200
}

CodePudding user response:

Below is the working version of your app. Try using optional chaining for your async datas while reading them. Plus, you should consider why you need useEffect which has search dependency that rerenders your component.

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

const Tempapp = () => {
  const [city, setCity] = useState('');
  const [search, setSearch] = useState('');
  const fetchApi = async () => {
    try {
      const url = `https://api.openweathermap.org/data/2.5/weather?q=${search}&units=metric&appid=83ea3057047027c6c4521d32d69250a0`;
      const res = await fetch(url);
      const data = await res.json();
      setCity(data);
    } catch (error) {
      console.log(error);
    }
  };
  const handleSubmit = (e) => {
    e.preventDefault();
    fetchApi();
  };
  return (
    <>
      <div className="box">
        <form onSubmit={handleSubmit} className="inputData">
          <input
            type="search"
            className="inputFeild"
            value={search}
            placeholder="Enter city"
            onChange={(event) => {
              setSearch(event.target.value);
            }}
          />
          <button type="submit">Search</button>
        </form>
        {!city ? (
          <p>Enter city or country to know weather</p>
        ) : (
          <div>
            <div className="info">
              <img
                src="../images/weather.png"
                alt="image"
                className="info-img"
              />
              <h1 className="temp">{city?.main?.temp} °Cel</h1>

              <h3 className="tempmin_max">
                Min : {city.main?.temp_min} °Cel | Max : {city.main?.temp_max}{' '}
                °Cel
              </h3>
            </div>
            <div className="wave -one"></div>
            <div className="wave -two"></div>
            <div className="wave -three"></div>
          </div>
        )}
      </div>
    </>
  );
};

export default Tempapp;

  • Related