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
Presumably this happens here:
What is
data
? It’s an empty array:Arrays, empty or otherwise, have no property called
weather
. Did you mean to read the first element of the array? For example:Though even then you’d need optional chaining, since the array is initially empty:
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:
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.
OpenWeatherMap’s site explains how to display icons:
The following should work: