Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ReactJS fails with an error "Cannot read property 'map' of undefined`"

Tags:

reactjs

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.

like image 533
31415926 Avatar asked Jul 16 '14 09:07

31415926


People also ask

How do you solve Typeerror Cannot read property map of undefined In react?

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.

How do I read a map in react JS?

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.

What does Cannot read property of undefined mean?

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.

How do you map an object in react?

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.


Video Answer


3 Answers

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.

like image 138
Paul O'Shannessy Avatar answered Oct 11 '22 23:10

Paul O'Shannessy


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!

like image 45
BenKarl Avatar answered Oct 12 '22 00:10

BenKarl


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')
);
like image 2
31415926 Avatar answered Oct 12 '22 00:10

31415926