admin管理员组文章数量:1287651
I am facing the error TypeError: Cannot read properties of undefined (reading 'map')
This code should return the name of the city in a card title which is defined in my other file but throwing an error.
Codes:
import React, {Component} from 'react';
import Body from './Body';
class Weather extends Component {
constructor(props) {
super(props);
this.state = {
weather: [],
};
}
async ponentDidMount() {
const url = `.json?key=${this.props.api}&q=Jaipur&aqi=no`;
let data = await fetch(url);
let parsedData = await data.json();
this.setState({
weather: parsedData.weather,
});
}
render() {
return (
<div className="container">
<div className="row">
{this.state.weather.map((element) => {
return (
<div className="col-md-4">
<Body city={element.location.name} />
</div>
);
})}
</div>
</div>
);
}
}
export default Weather;
I am facing the error TypeError: Cannot read properties of undefined (reading 'map')
This code should return the name of the city in a card title which is defined in my other file but throwing an error.
Codes:
import React, {Component} from 'react';
import Body from './Body';
class Weather extends Component {
constructor(props) {
super(props);
this.state = {
weather: [],
};
}
async ponentDidMount() {
const url = `http://api.weatherapi./v1/current.json?key=${this.props.api}&q=Jaipur&aqi=no`;
let data = await fetch(url);
let parsedData = await data.json();
this.setState({
weather: parsedData.weather,
});
}
render() {
return (
<div className="container">
<div className="row">
{this.state.weather.map((element) => {
return (
<div className="col-md-4">
<Body city={element.location.name} />
</div>
);
})}
</div>
</div>
);
}
}
export default Weather;
Share
Improve this question
edited Oct 16, 2021 at 12:28
nima
8,92512 gold badges40 silver badges55 bronze badges
asked Sep 29, 2021 at 4:17
Yatharth SinghYatharth Singh
291 gold badge1 silver badge3 bronze badges
3
-
What is the value of
parsedData.weather
that you are updatingthis.state.weather
to? Is it an array? – Drew Reese Commented Sep 29, 2021 at 4:41 - yes this will store an array of all my weather details fetched from the api – Yatharth Singh Commented Oct 1, 2021 at 5:40
-
Please show us the value of
parsedData
. From what I can tell,this.state.weather
is a defined array on the initial render, so somehow after you fetch data and update state,this.state.weather
is no longer defined. This is why you can't read.map
or.length
and an error is thrown. If I had yourthis.props.api
value I'd just reproduce this myself and see what the response value is. – Drew Reese Commented Oct 1, 2021 at 16:13
3 Answers
Reset to default 6The Problem:
your weather array is empty before the API call so using this.state.weather.map
will cause the error.
The Solution:
There are two important things before using the map
with arrayes:
- check for the definition of the array (is the array defined and exists?)
- check its length (is the array has some content?)
First
check its declaration/definition by a simple if
statement:
{
if(myArrayOfData) {
myArrayOfData.map(
// rest of the codes ...
)
}
}
Or with using ?
shorthanded of if
{
myArrayOfData?.map(
// rest of the codes ...
)
}
Second
check for the contents of the array and use the map
function after checking its length (which tells you the data has arrived from the API call etc. and is ready to process)
{
if(myArrayOfData) {
if(myArrayOfData.length > 0) {
myArrayOfData.map(
// rest of the codes ...
)
}
}
}
Finally:
while the above snippet works properly, you can simplify it by checking both if
conditions together:
{
if(myArrayOfData?.length > 0) {
myArrayOfData.map(
// rest of the codes ...
)
}
}
So, simply make some changes in the return of Weather
ponent:
<div className="row">
{
if(this.state.weather?.length > 0) {
this.state.weather.map((element) => {
return (
<div className="col-md-4" key={element.id}> // also don't forget about the passing a unique value as key property
<Body city={element.location.name}/>
</div>
);
})
}
}
</div>
Optional:
In real-world examples, you may need to show some loading ponents while the data is fetching.
{
if(myArrayOfData?.length > 0) {
myArrayOfData.map(
// rest of the codes ...
)
} else {
<Loading />
}
}
Be Aware
const anEmptyArray = []
if(anEmptyArray){
// rest of the codes ...
}
The result of parison on if(anEmptyArray)
is always true
with an empty array.
the simplest way is just to add "this.state.weather &&" before map method, first it will make sure that "this.state.weather" is defined and then run the code, example is below
{this.state.weather && this.state.weather.map((element) => {
return (
<div className="col-md-4">
<Body city={element.location.name} />
</div>
);
})}
Lets make an assumption that parsedData.weather
have correct data type. You should make a conditional logic, to check this.state.weather
should have a value from API.
Here's an example
render() {
const { weather } = this.state; // Access the state `weather`
return (
<>
<div className="container">
<div className="row">
{ /* This way use conditional ternary operator */ }
{weather.length ? weather.map((element) => {
return (
<div className="col-md-4">
<Body city={element.location.name}/>
</div>
);
}) : <span>Loading...</span>}
</div>
</div>
</>
);
}
本文标签: javascriptTypeError Cannot read properties of undefined (reading 39map39) React JSStack Overflow
版权声明:本文标题:javascript - TypeError: Cannot read properties of undefined (reading 'map') React JS - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741256473a2366771.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论