Home > Blockchain >  React.js with OpenWeatherMap, getting weathers.map is not a function
React.js with OpenWeatherMap, getting weathers.map is not a function

Time:03-05

I am learning React.js for college and am a bit stuck. I am getting this error:

weathers.map not a function

I am sure it's something simple but cant figure it out! It is a standard create-react-app. Created a directory called components and these 2 files live there.

Weathers.js:

import {useState} from 'react'
import axios from 'axios'
import Weather from './Weather'

function Weathers() {
    const [weathers, setWeathers] = useState([])
    const [city, setCity] = useState('')
    const API = {
    link: "http://api.openweathermap.org/data/2.5/weather?q=",
    key: "&appid=xxxxx"
    }

    function handleSearchCity(e) {
        e.preventDefault()
        setCity(e.target.value)
    }

    async function searchWeathers(e) {
        e.preventDefault()
        console.log()
        var response = await axios.get(API.link   city   API.key)
        console.log(response)
        setWeathers(response.data)
    }
    return (
        <div>
        <input value={city} onChange={handleSearchCity} />
        <button onClick={searchWeathers}>Search</button>
        {
            weathers.map(function(i, index){
                return (
                <div>
                    <Weather name={i.name} />
                </div>
                )
            })
        }
        </div> 
    )
}
export default Weathers;

Weather.js:

import {useState} from 'react'

function Weather(props) {
return (
    <div>
        {props.name}
        </div>
    )
}

export default Weather;

App.js:

import logo from './logo.svg';
import './App.css';
import Weathers from './components/Weathers'

function App() {
  return (
    <div>
      <Weathers />
    </div>
  );
}

export default App;

CodePudding user response:

You are getting an error because the result you are getting from the api is not an array. It is an object that looks like this (for London):

{
    "coord": {
        "lon": -0.1257,
        "lat": 51.5085
    },
    "weather": [
        {
            "id": 500,
            "main": "Rain",
            "description": "light rain",
            "icon": "10n"
        }
    ],
    "base": "stations",
    "main": {
        "temp": 278.91,
        "feels_like": 276.51,
        "temp_min": 277.25,
        "temp_max": 280.02,
        "pressure": 1021,
        "humidity": 88
    },
    "visibility": 10000,
    "wind": {
        "speed": 3.09,
        "deg": 330
    },
    "rain": {
        "1h": 0.89
    },
    "clouds": {
        "all": 100
    },
    "dt": 1646438029,
    "sys": {
        "type": 2,
        "id": 2019646,
        "country": "GB",
        "sunrise": 1646375984,
        "sunset": 1646415906
    },
    "timezone": 0,
    "id": 2643743,
    "name": "London",
    "cod": 200
}

If you want the name propriety inside the result, you could get it like so:

import {useState} from 'react'
import axios from 'axios'
import Weather from './Weather'

function Weathers() {
    const [weathers, setWeathers] = useState()
    const [city, setCity] = useState('')
    const API = {
    link: "http://api.openweathermap.org/data/2.5/weather?q=",
    key: "&appid=xxxxx"
    }

    function handleSearchCity(e) {
        e.preventDefault()
        setCity(e.target.value)
    }

    async function searchWeathers(e) {
        e.preventDefault()
        console.log()
        var response = await axios.get(API.link   city   API.key)
        console.log(response)
        setWeathers(response.data)
    }
    
    return (
       <div>
         <input value={city} onChange={handleSearchCity} />
         <button onClick={searchWeathers}>Search</button>
         {weathers && <Weather name={weathers.name} />}
       </div> 
    )
}
export default Weathers;

CodePudding user response:

Since weathers is initialized to an empty array, you shouldn't actually have the error weathers.map is not a function. Maybe you can add a conditional rendering to only return the jsx expression when you get the weathers data from the API.

return weathers && (
        <div>
        // ...
        </div> 
    )
}
export default Weathers;
  • Related