Following react.js tutorial I've got an error: Uncaught TypeError: Cannot read property 'map' of undefined
.
I was following the tutorial strict but stuck at Fetching from the server part. The error appears when I feed commentBox with url data instead of the hardcoded JSON data.
/** @jsx React.DOM */
var converter = new Showdown.converter();
var data = [
{ Author: "Daniel Lo Nigro", Text: "Hello ReactJS.NET World!" },
{ Author: "Pete Hunt", Text: "This is one comment" },
{ Author: "Jordan Walke", Text: "This is *another* comment" }
];
var Comment = React.createClass({
render: function() {
var rawMarkup = converter.makeHtml(this.props.children.toString());
return (
<div className="comment">
<h2 className="commentAuthor">
{this.props.author}
</h2>
<span dangerouslySetInnerHTML={{__html: rawMarkup}} />
</div>
);
}
});
var CommentList = React.createClass({
render: function() {
var commentNodes = this.props.data.map(function (comment) {
return <Comment author={comment.Author}>{comment.Text}</Comment>;
});
return (
<div className="commentList">
{commentNodes}
</div>
);
}
});
var CommentForm = React.createClass({
render: function() {
return (
<div className="commentForm">
Hello, world! I am a CommentForm.
</div>
);
}
});
var CommentBox = React.createClass({
render: function() {
return (
<div className="commentBox">
<h1>Comments</h1>
<CommentList data={this.props.data} />
<CommentForm />
</div>
);
}
});
React.renderComponent(
//<CommentBox data={data}/>, //this works fine
<CommentBox url="/comments" />, //Changing data feet to url produces an error
document.getElementById('content')
);
The request at http://localhost:52581/comments
is working and returns a JSON data:
[{"Author":"Daniel Lo Nigro","Text":"Hello ReactJS.NET World!"},{"Author":"Pete Hunt","Text":"This is one comment"},{"Author":"Jordan Walke","Text":"This is *another* comment"}]
Any advice would be a big help for me. Thanks.
The "cannot read property 'map' of undefined" error occurs when we call the map() method on an undefined value, most often when the map method is called before the data from an API request has arrived. To solve the error, initialize the value you're mapping over to an empty array.
In React, the map method is used to traverse and display a list of similar objects of a component. A map is not a feature of React. Instead, it is the standard JavaScript function that could be called on an array. The map() method creates a new array by calling a provided function on every element in the calling array.
The "Cannot read properties of undefined" error occurs when trying to access a property on an undefined value. You often get undefined values when: accessing a property that does not exist on an object. accessing an index that is not present in an array.
To map through an object's value in React: Use the Object. values() method to get an array of the object's values. Call the map() method on the array of values.
In CommentBox, this line is the problem: <CommentList data={this.props.data} />
You no longer have props.data
since you are passing a URL in instead of a JS object.
Your 2nd one works because you use state and default the value to an empty array, which can still have map run on it.
I also had this exact problem - the tutorial doesn't make it clear at this point, but I don't think the app is actually supposed to be properly loading the data at this point. If you continue working through the tutorial it has you build an ajax call using this.props.url which loads the data. Just FYI for anyone else who might be confused, just keep pressing on, all is good!
This one works.
/** @jsx React.DOM */
var converter = new Showdown.converter();
var data = [
{ Author: "Daniel Lo Nigro 2", Text: "Hello ReactJS.NET World! 2" },
{ Author: "Pete Hunt 2", Text: "This is one comment 2" },
{ Author: "Jordan Walke 2", Text: "This is *another* comment 2" }
];
var Comment = React.createClass({
render: function() {
var rawMarkup = converter.makeHtml(this.props.children.toString());
return (
<div className="comment">
<h2 className="commentAuthor">
{this.props.author}
</h2>
<span dangerouslySetInnerHTML={{__html: rawMarkup}} />
</div>
);
}
});
var CommentList = React.createClass({
render: function() {
var commentNodes = this.props.data.map(function (comment) {
return <Comment author={comment.Author}>{comment.Text}</Comment>;
});
return (
<div className="commentList">
{commentNodes}
</div>
);
}
});
var CommentForm = React.createClass({
render: function() {
return (
<div className="commentForm">
Hello, world! I am a CommentForm.
</div>
);
}
});
var CommentBox = React.createClass({
getInitialState: function() {
return {data: []};
},
componentWillMount: function() {
var xhr = new XMLHttpRequest();
xhr.open('get', this.props.url, true);
xhr.onload = function() {
var data = JSON.parse(xhr.responseText);
this.setState({ data: data });
}.bind(this);
xhr.send();
},
render: function() {
return (
<div className="commentBox">
<h1>Comments</h1>
<CommentList data={this.state.data} />
<CommentForm />
</div>
);
}
});
React.renderComponent(
//<CommentBox data={data}/>,
<CommentBox url="/comments" />,
document.getElementById('content')
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With