skip to Main Content

I’m currently working on a project where I need to extract an icon from an object or an array. However, I’m encountering difficulties in doing so. My approach involves storing the icon in a variable and then passing it as a prop to another component. Unfortunately, despite following this approach, the functionality isn’t working as I anticipated.

This is the error i’m getting in the console: "Cannot read properties of undefined (reading ‘0’)" That happend when i implement this code <img src={props.icon} alt="cloud" /> with out of that works fine

Here is the code:

import React, { useEffect, useState } from "react";
import Weather from "./components/Weather";
import "./App.css";

function App() {
  const [search, setSearch] = useState("");
  const [data, setData] = useState([]);

  useEffect(() => {
    fetch(
      `https://api.openweathermap.org/data/2.5/weather?q=${search}&appid=1769e69d20183ccd0c32ac3215db1d40&units=metric`
    )
      .then((response) => response.json())
      .then((json) => setData(json))
      .catch((error) => console.error(error));
  }, [search]);

  const handleInput = (event) => {
    setSearch(event.target.value);
  };

  let icon = data.weather[0].icon + ".png";

  return (
    <div>
      <Weather icon={icon} inputValue={handleInput} showItems={data} />
    </div>
  );
}

export default App;

import "./style/Weather.css";
import "@fortawesome/fontawesome-free/css/all.css";

function Weather(props) {
  //   const data = [
  //     {
  //       coord: {
  //         lon: -0.1257,
  //         lat: 51.5085,
  //       },
  //       weather: [
  //         {
  //           id: 804,
  //           main: "Clouds",
  //           description: "overcast clouds",
  //           icon: "04d",
  //         },
  //       ],
  //       base: "stations",
  //       main: {
  //         temp: 285.69,
  //         feels_like: 285.19,
  //         temp_min: 284.29,
  //         temp_max: 286.64,
  //         pressure: 1015,
  //         humidity: 84,
  //       },
  //       visibility: 10000,
  //       wind: {
  //         speed: 5.14,
  //         deg: 210,
  //       },
  //       clouds: {
  //         all: 100,
  //       },
  //       dt: 1710850556,
  //       sys: {
  //         type: 2,
  //         id: 2075535,
  //         country: "GB",
  //         sunrise: 1710828286,
  //         sunset: 1710871895,
  //       },
  //       timezone: 0,
  //       id: 2643743,
  //       name: "London",
  //       cod: 200,
  //     },
  //   ];

  return (
    <div className="container">
      <div className="weather-container">
        <input
          onChange={props.inputValue}
          type="text"
          placeholder="Enter a city name"
        />
        <p>{props.showItems.name}</p>
        <img src={props.icon} alt="cloud" />
        {props.showItems.main && <p>{props.showItems.main.temp.toFixed()}°C</p>}
      </div>
    </div>
  );
}

export default Weather;

2

Answers


  1. Cannot read properties of undefined (reading ‘0’)

    Presumably this happens here:

    let icon = data.weather[0].icon + ".png";
    

    What is data? It’s an empty array:

    const [data, setData] = useState([]);
    

    Arrays, empty or otherwise, have no property called weather. Did you mean to read the first element of the array? For example:

    let icon = data[0].weather[0].icon + ".png";
    

    Though even then you’d need optional chaining, since the array is initially empty:

    let icon = data[0]?.weather[0].icon + ".png";
    

    You can include optional chaining any time you are accessing a property/index which may not exist. Keep in mind of course that icon would then be something unexpected, such as "null.png" or "undefined.png".

    You could also set it to some default and conditionally override it. For example:

    let icon = "default.png";
    if (data.length > 0) {
      icon = data[0].weather[0].icon + ".png";
    }
    

    Of course, all of this depends entirely on what data actually contains. You initialize it as an array, but then the line of code we’re talking about here assumed it was an object. Which is it?

    You’ll need to know the structure of your data in order to use that data. But any way you look at it, how you use it needs to support both the initial (empty) state and the later state in which the data is populated.

    Login or Signup to reply.
  2. OpenWeatherMap’s site explains how to display icons:

    https://openweathermap.org/weather-conditions

    The following should work:

    <img src={`https://openweathermap.org/img/wn/${props.icon}.png`} alt="cloud" />
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search