'React functional: Cannot read properties of undefined, API. Acess to child

a little help I'm new in React

Why the useEffectworks fine, but the data.name render fines, but the e.g data.main.lat he dont have acess to, even with map. The data in the child he can't get it

I hope this question make sense 🙂

import React, { useEffect, useState } from 'react';
import { useLocation } from 'react-router-dom';
import axios from "axios";
const API_KEY = ''
function Home() {
    const [data, setData] = useState([]);
    const location = useLocation();

    let val = location.pathname.slice(1)
    useEffect(() => {
        axios.get(`https://api.openweathermap.org/data/2.5/weather?q=${val}&appid=${API_KEY}`)
            .then((response) => {
                // console.log(response);
                setData(response.data)
            }).catch((error) => {
                // console.error("Error fetching data: ", error);
                // setError(error);
            });
    }, []);
    return (
        <div>
            <h2>Home</h2>
            <p>{data.name}</p>
            {
                data.main.map((i) => {
                    <h1>{i.lat}</h1>
                })
            }
        </div>


    );
};

response

{
base: "stations"
clouds:
all: 0
[[Prototype]]: Object
cod: 200
coord: {lon: 2.3488, lat: 48.8534}
dt: 1646247623
id: 2988507
main:
feels_like: 281.92
humidity: 65
pressure: 1019
temp: 282.42
temp_max: 283.03
temp_min: 281.41
[[Prototype]]: Object
name: "Paris"
sys:
country: "FR"
id: 6550
sunrise: 1646202672
sunset: 1646242483
type: 1
[[Prototype]]: Object
timezone: 3600
visibility: 10000
weather: Array(1)
0: {id: 800, main: 'Clear', description: 'clear sky', icon: '01n'}
length: 1
[[Prototype]]: Array(0)
wind:
deg: 100
speed: 1.54

How i have access to <p> {data.coord.lat}</p> in the return. this shows error Cannot read properties of undefined (reading 'lat')



Solution 1:[1]

When your component first renders, data is an empty array. Since arrays don't have a main property, you'll get an error because you're trying to use a map function of undefined.

What you can do is

{
                data?.main?.map((i) => (
                    <h1>{i.lat}</h1>
                ))
}

Which will only call the map function if data.main exists. Also, make sure that data.main in your response is an array as well, otherwise map won't work

Solution 2:[2]

You can try to check data.main.length

{
         data.main && data.main.map((i) => {
                <h1>{i.lat}</h1>
            })
        }

Solution 3:[3]

You're not returning <h1>{i.lat}</h1> in the callback to data.main.map() method.

Either add a return statement:

data.main.map((i) => {
    return <h1>{i.lat}</h1>
})

Alternatively remove the curly brackets to implicitly return:

data.main.map((i) => <h1>{i.lat}</h1>)

See Array.map on MDN

Solution 4:[4]

  1. According to open weather API doc main you're trying to map is an object, not an array.

https://openweathermap.org/current#name

Instead of map simply access it as an object : <p>{data.coord.lat}</p>

  1. lat element exist in coord not main object.

3.API call take some time to provide data and you're mapping state which is still empty when there's no response from API maybe you can add loading state when you're waiting response.

Live Demo: https://codesandbox.io/s/awesome-engelbart-gxzqcd?file=/src/App.js

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Areg Nikoghosyan
Solution 3 Svenskunganka
Solution 4