Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ReactJS and complex JSON object

I followed ReactJS tutorial, which is quite simple to accomplish more complex stuff.

In my case, I would like to use a complex JSON object, which contains a map, a single value, a list, etc... Here is the code:

    var NotificationStatus = React.createClass({
    loadNotificationsFromServer: function() {
      $.ajax({
        url: this.props.url,
        dataType: 'json',
        success: function(data) {
          this.setState({data: data});
          console.log(this.state.data.notificationType);
        }.bind(this)
      });
    },
    getInitialState: function() {
      return {data: {}};
    },
    componentWillMount: function() {
      this.loadNotificationsFromServer();
      setInterval(this.loadNotificationsFromServer, this.props.pollInterval);
    },
    render: function() {
      return (
        <div>
          <li className="dropdown-menu-title">
              <span>You have {this.state.data.notificationCount} notifications</span>            
          </li>
          <Notifications data={this.state.data.notificationType} />
        </div>  
      );
    }
  });



  var Notifications = React.createClass({
    render: function() {
      var notificationNodes = this.props.data.map(function (notif, index) {
        return <Notification key={index}>{notif.type}</Notification>;
      });
      return <li>{notificationNodes}</li>;
      }
  });

  var Notification = React.createClass({
    render: function() {
      return (
        <a href="#">
              <span className="icon blue"><i className={this.props.children == "user" ? 'icon-user' : 'icon-comment-alt'}></i></span>
              <span className="message">{this.props.children}</span>           
              <span className="time">1 min</span>
          </a>
      );
    }
  });

  React.renderComponent(
    <NotificationStatus url="/data/notifications.json" pollInterval={2000} />,
    document.getElementById('notificationbar')
  );

And this is a sample from the JSON:

    {
    "notificationCount": "1",
    "notificationType": [
       {
         "type": "update",
         "text": "New Update"
       },
       {
          "type": "user",
          "text": "New User"
       }
     ]
    }

When I try to get notificationType, an error "this.props.data is undefined" is raised at this point

    var notificationNodes = this.props.data.map(function (notif, index) {

I really don't see what's wrong with the declaration, and when I get the JSON at the ajax level, I do have a map (verified with the console.log).

Any help would be great.

Thanks a lot.

like image 724
Seif Eddine Mouelhi Avatar asked Dec 16 '22 00:12

Seif Eddine Mouelhi


1 Answers

When your component first renders, NotificationStatus's this.state.data will be {} because that's what's returned from getInitialState. That means that when you render

<Notifications data={this.state.data.notificationType} />

you're passing {}.notificationType or undefined:

<Notifications data={undefined} />

So when Notifications first renders, this.props.data isn't a list. It depends on your application what the right fix here is, but perhaps you want to initialize with data: null and add this to the top of NotificationStatus's render method:

if (!this.state.data) {
    return <div>Loading...</div>;
}
like image 195
Sophie Alpert Avatar answered Dec 17 '22 13:12

Sophie Alpert