Reputation: 23
I have an array that contains objects, inside an object. I can console.log the first object and the array, but when i try to access the objects within the array or use the map-function on the array i get an error that says "Can't read property of undefined".
I have thoroughly searched SO and other sites for similar problems and found some but no answers seems to work for me.
The object looks like this:
{
answers: [{…}],
createdAt: "2019-01-23T10:50:06.513Z",
nested: {kebab: "jjjj", sås: 2, sallad: "kkk"},
text: "weaxcc",
/* etc... */
}
And i can access it using: this.state.data
I want to access objects inside the answers-array like:
this.state.data.answers[0].text
or even :
this.state.data.answers.map().....
But that gives me 'Cannot read property '0' of undefined. The answers-array is not empty.
Any help is appreciated!
EDIT This is how the objects ends up in my state.
getQuestionFromDb = () => {
axios.get(`http://localhost:3000/questions/${this.state.id}`)
.then(res => this.setState({
data: res.data
}));
};
This function is called in the ComponentDidMount()-method.
Here is my render function (the console.log is causing the error):
render() {
return (
<div className="main-content">
<h2>{this.state.data.text} </h2>
{console.log(this.state.data.answers[0].text)}
<p>Introducing <strong>{this.state.id}</strong>, a teacher who loves teaching courses about <strong>{this.state.id}</strong>!</p>
<input
type="text"
onChange={e => this.setState({ message: e.target.value })}>
</input>
<button onClick={() => {this.handleAnswerPost(this.state.message)}}>Answer</button>
</div>
);
}
}
Upvotes: 2
Views: 3735
Reputation: 26165
componentDidMount
is getting called when your component becomes part of the DOM but the call you do to populate your state is async due to XHR, which may take 100-300ms more to get the data in your component, so this.state.data.answers
won't be available in the initial render()
cycle.
since you mentioned using a loop, I suggest setting an initial state shape like
this.state = {
data: {
answers: []
}
}
your initial render won't have anything to loop but as soon as it resolves the data and sets the new state, it will render correctly.
alternatively you can
return this.state.data.answers.length ? loopItemsHere : <div>Loading..</div>
obviously, loopItemsHere
can be anything you write to show the answers.
Upvotes: 3
Reputation: 2938
This might not be working when data doesnt contain answers[]
at the very first mount for a component.
You may wanna check for your array's existance as following:
const { data } = this.state;
data.hasOwnProperty('answers') && console.log(data.answers[0]);
Upvotes: 1
Reputation: 3487
There may be a number of reasons that could cause the data object not to be shown:
The object was not in state at the time of it being called. This may be caused by an async operator not loading in the data. E.g. if you are requesting for the object from the database, chances are that at the time of making a call to retrieve the data (this.state.data
), the response had not been given.
The object may not have been parsed into string. Try running console.log(typeof this.state.data)
. If the output is string
, then you may have to parse it. If the output is undefined
, then point one is valid
Upvotes: 0
Reputation: 2644
The reason we can't access object key in Javascript, usually it is because the variable/value is not the type of Object. Please ensure that this.state.data
type is Object. You can try to console.log( typeof this.state.data )
. We should expect that it is output object
. If the type is string
, you should parse it first with JSON.parse()
.
Upvotes: 0