I am learning ReactJS for college and am a bit stuck. I am getting error "weathers.map not a function"
i am sure its something simple but cant figure it out!
Thank you
so standard create app in JS. created DIR 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;
and Weather.js
import {useState} from 'react'
function Weather(props) {
return (
<div>
{props.name}
</div>
)
}
export default Weather;
and app.js if its needed
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)
}
// you can change this loader to whatever you want
if(!weathers){
return <div>Loading...</div>
}
return (
<div>
<input value={city} onChange={handleSearchCity} />
<button onClick={searchWeathers}>Search</button>
<div>
<Weather name={weathers.name} />
</div>
</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;