Baz Baz - 3 months ago 22
React JSX Question

Map the values of an associate array

I have the following regex components:

const CommentBox = React.createClass({
render: function() {
return (
<div className="commentBox">
<h1>Comments</h1>
<CommentList comments={this.props.comments}/>
<CommentForm />
</div>
);
}
});

var CommentList = React.createClass({
render: function() {

return <div className="commentList">
{this.props.comments.toList().map(comment =>
<Comment author={comment.author} key={comment.id}>
{comment.text}
</Comment>
)}
</div>
}
});


The data in
this.props.comments
is as follows:

{"comments":{"3":{"id":3,"author":"Me","text":"This is one comment!"},"4":{"id":4,"author":"You","text":"This is one more comment!"},"5":{"id":5,"author":"Bar","text":"This is one comment!"},"6":{"id":6,"author":"Foo","text":"This is one more comment!"},"7":{"id":7,"author":"Baz","text":"This is one comment!"},"8":{"id":8,"author":"Boo","text":"This is one more comment!"}}}


Please note that
this.props.comments
is an
immutable.Map
.

How do I map the values in the
immutable.Map
this.props.comments
without converting its values to a List first via (
toList
) where I instead simply iterate over the values.

UPDATE:

I get an error saying that comment.get is undefined when I try:

const CommentList = ({comments}) =>
<div className="commentList">
{comments.map(comment =>
<Comment author={comment.get('author')} key={comment.get('id')}>
{comment.text}
</Comment>)}
</div>


However the following code works as expected:

const CommentList = ({comments}) =>
<div className="commentList">
{comments.valueSeq().map( (comment) =>
<Comment author={comment.author} key={comment.id}>
{comment.text}
</Comment>
)}
</div>


Why is that?

Answer

Immutable.Map objects have map functions by default. You can iterate through it just like you would iterate through an immutable list. The only caveat is that the result would be a Map with the same keys of that of the iterated element, but still their corresponding values will be what we return from the map() callback function. Since Map doesn't have deep conversion of objects, I suggest using fromJS(). Please checkout this thread here: Difference between fromJS and Map.

You can try the below code:

const comments = fromJS({
 "3":{"id":3,"author":"Me","text":"This is one comment!"},
 "4":{"id":4,"author":"You","text":"This is one more comment!"},
 "5":{"id":5,"author":"Bar","text":"This is one comment!"},
 "6":{"id":6,"author":"Foo","text":"This is one more comment!"},
 "7":{"id":7,"author":"Baz","text":"This is one comment!"},
 "8":{"id":8,"author":"Boo","text":"This is one more comment!"}
})

comments.map(comment =>
         <Comment author={comment.get('author')} key={comment.get('id')} >
            {comment.get('text')}
        </Comment>);