Jeanmichel Cote Jeanmichel Cote - 5 months ago 28
Javascript Question

Generating components through iteration

Something weird is going on:

This is my initial state (a .js file)

import moment from 'moment';

let date = moment();
var previousDate = moment("2015-12-25");

export const projects = [
{
"id": 0,
"metadata": {
"fields":
[{
"id": 1,
"order": 1,
"name": "Name",
"value": "Collection 1"
},
{
"id": 2,
"order": 2,
"name": "Created On",
"value": date
},
{
"id": 3,
"order": 3,
"name": "Last Modified On",
"value": previousDate
},
{
"id": 4,
"order": 4,
"name": "Status",
"value": "Filed"
}],

"tags":
[{
"id": 1,
"order": 1,
"value": "tag1"
},
{
"id": 2,
"order": 2,
"value": "tag2"
},
{
"id": 3,
"order": 3,
"value": "tag3"
},
{
"id": 4,
"order": 4,
"value": "tag4"
}]
}
}


This is
ProjectsList.js
:

import React from 'react';
import Project from './Project';
import { projects } from 'initialState';

export default (props) => {
return(
<div className="projectsList">
{projects.map(project => (
<article key={project.id}><Project fields={project.metadata.fields} /></article>
))}
</div>
)
}


And this one's
Project.js
:

import React from 'react';

export default (props) => {
return(
<ul className="fields">
{props.fields.map(field => <li key={field.id}>{field.name}</li>) }
</ul>
)
}


I am trying to render a bunch of projects in a list, and every project contains a bunch of metadata key-value pairs that it shows.

So basically, the wiring does not matter, it all works fine.

Except for this:

If you look up at the initial state file (first one up there), there is an array of multiple objects in
fields
. Each object shows 4 key-value pairs


  • id

  • order

  • name

  • value



Now, in
Project.js
, the line where I go

{props.fields.map(field => <li key={field.id}>{field.name}</li>) }


looks like I can switch the
{field.name}
for
{field.id}
, to show the id in text. Or I can go
{field.order}
, to display the order.

But weirdly enough, if I want to show the actual value of the field, like so
{field.value}
, it throws.

invariant.js?4599:38


Uncaught Invariant Violation: Objects are not valid as a React child (found: Mon Jun 20 2016 21:40:33 GMT-0400). 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 `StatelessComponent`.


I even went as far (sigh) as changing the string
value
in every
fields
to
val
, juste to make sure
value
wasn't some kind of a reserved word.

Still threw.

Anybody can help me understand what I have done wrong, here?

Thanks Guys.

Answer

You are assigning to variable values to the value property in your state file, which are most likely not strings, but objects:

export const projects = [{
    "id": 0,
    "metadata": {
      "fields": 
        [
        ...
        {
          "id":     2,
          "order":  2,
          "name":   "Created On", 
          "value":  date                 // one
        },
        {
          "id":     3,
          "order":  3,
          "name":   "Last Modified On", 
          "value":  previousDate         // and another one
        },
        ...
        ]
    ...    
    }
}
Comments