1

I'm trying to render an object inside an element (Panel element in react-bootstrap).

import React, { PropTypes } from 'react';
import { Panel } from 'react-bootstrap';

const NetworkDetail = React.createClass({
  render () {
    return (
      <Panel header="Network Details" bsStyle="info">
        {this.props.dataDetail && Object.keys(this.props.dataDetail).map(function(detail, id) {
            return <span key={id}>{this.props.dataDetail[detail]}</span>;
        }.bind(this))}
      </Panel>
    )
  }
})

export default NetworkDetail

But that doesn't work. The error thrown is

Uncaught Invariant Violation: Objects are not valid as a React child (found: object with keys {self}). If you meant to render a collection of children, use an array instead or wrap the object using createFragment(object) from the React add-ons. Check the render method of 'NetworkDetail'.

What I don't understand is that if I use

return <span key={id}>{this.props.dataDetail.myProperty}</span>;

it works.

How can I render all the properties and values of my object ?

4
  • 2
    Are you sure none of the keys in props.dataDetails might resolve an object in this.props.dataDetail[detail]? Commented Jul 18, 2016 at 19:18
  • Oh snap, the dataDetail object has actually a property named _links which is an object... (the app consumes a REST HATEOAS backend). If this _linksobject is the cause, how should I get rid of ? Maybe with underscore.js (I actually already use underscore.js to reformat my data) ? Commented Jul 18, 2016 at 20:10
  • 1
    You could use Underscore's omit function to filter _links. A better option might be to create a list of the keys you want to render and use Underscore's pick function instead. See: underscorejs.org/#omit Commented Jul 18, 2016 at 20:39
  • Thank you for your help. I accepted the answer below but you totally nailed the initial problem (the object inside my object). Thanks again. Commented Jul 19, 2016 at 8:36

1 Answer 1

8

It looks to me that this component is a stateless/dumb component. So, you should begin by reading about how to write these kind of components to maximize efficiency: https://facebook.github.io/react/docs/reusable-components.html#stateless-functions

Then, to fix your component, you should notice that

    {this.props.dataDetail && Object.keys(this.props.dataDetail).map(function(detail, id) {
        return <span key={id}>{this.props.dataDetail[detail]}</span>;
    }.bind(this))}

is just a conditional statement. Notice your '&&'. So, assuming that this.props.dataDetail is an object, you can rewrite this component like this:

import React, { PropTypes } from 'react';
import { Panel } from 'react-bootstrap';

const NetworkDetail = ({dataDetail}) => 
  <Panel header="Network Details" bsStyle="info">
    {
      Object.keys(dataDetail).filter(v => v !== '_links').map((detail, id) => <span key={id}>{dataDetail[detail]}</span>)
    }
  </Panel>

export default NetworkDetail;

Let me know if this works!

Sign up to request clarification or add additional context in comments.

1 Comment

glad it worked out for you @Clafou. please let me know if you run into any other trouble =)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.