Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Simple weather app breaking at weather.main.temp variable

I’m building a really basic weather app with React hooks, codesandbox.io and OpenWeatherAPI.
It’s breaking at const temp = forecast.main.temp; and returning "TypeError: Cannot read properties of undefined (reading ‘temp’)" It actually does run when I initially write it but breaks if I add another variable or have to edit the temp variable in any way.

import React, { useState } from "react";
import "../styles.css";
import CityCard from "./cityCard";

export default function GetWeather() {

  const [city, setCity] = useState('');
  const [forecast, setForecast] = useState([]);

  const getCity = async (e) => {
    e.preventDefault();

  //API variables 
  const url = `https://api.openweathermap.org/data/2.5/weather?q=${city}&units=imperial&appid=${APIkey}`;
  
  //fetch response
  try {
  const res = await fetch(url);
  const data = await res.json();
  setForecast(data);
  } catch (err) {
    console.error(err);
  }

};

  return (
    //basic input form to search by city
    <div>
      <h1 className="title">Weather App</h1>
      <CityCard forecast={forecast} />
      <form className="form" onSubmit={getCity}>
      <label className="label" htmlFor="city">
      <p>Search by City</p>
      </label>
      <input 
        className="input" 
        type="text" 
        name="query place"
        placeholder="i.e. Seattle"
        value={city} onChange={(e) => setCity(e.target.value)}
        >
      </input>
      <button 
      className="button" 
      type="submit"
      >Search</button>
      </form>
    </div>
  );
}

CityCard

import React from "react";
import "../../src/styles.css";

export default function CityCard({ forecast }) {
  //pass props to cards
  const cityName = forecast.name;
  const temp = forecast.main.temp;

  return (
      <div className="card-container">
        <p className="card-title">{cityName}</p>
        <p>Temp: {temp} </p>
      </div>

  );
}

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Issue

The initial forecast state is declared as an array:

const [forecast, setForecast] = useState([]);

and passed to CityCard on forecast prop:

<CityCard forecast={forecast} />

then accessed as if it were an object:

function CityCard({ forecast }) {
  //pass props to cards
  const cityName = forecast.name;  // OK, undefined
  const temp = forecast.main.temp; // Not OK, can't access temp of undefined

  return (
      <div className="card-container">
        <p className="card-title">{cityName}</p>
        <p>Temp: {temp}</p>
      </div>

  );
}

Solution

Use Optional Chaining operator to protect against null/undefined property accesses.

function CityCard({ forecast }) {
  //pass props to cards
  const cityName = forecast?.name;
  const temp = forecast?.main?.temp;

  return (
      <div className="card-container">
        <p className="card-title">{cityName}</p>
        <p>Temp: {temp}</p>
      </div>

  );
}

Or wait to render CityCard when there’s a valid forecast data to display.

const [forecast, setForecast] = useState();

...

{forecast?.name && forecast?.main?.temp && <CityCard forecast={forecast} />}

OpenWeather JSON API response

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading