Can I send an array of objects to child component in React

<%= @topic_view.topic.title %>
<%= @topic_view.topic.average_rating %> <%= @topic_view.topic.posts.count { |p| !!p.custom_fields['rating'] } %>

I am sending data to a child component that is an array of objects:


But when I try to render anything with that data, I keep running into errors.

First, I tried to render the first element of the array in a <p></p> tag just to see what was happening.

Code:

const BarChart1 = props => {
  const { barData } = props;
  console.log(props.barData); //Why do I have to access props.barData instead of just barData?

  return (
    
    <div>
      <div>
        <p>{props.barData}</p>
      </div>
    </div>
  );
};

Error:
Invariant Violation: Objects are not valid as a React child (found: object with keys {LEASED, RENTED, GIVEN BY GOVERNMENT, NA}). If you meant to render a collection of children, use an array instead.

But props.barData IS an array…isn’t it?

Then I looked up answers on StackOverflow and all their solutions seem to treat the data like an array: https://stackoverflow.com/questions/19590865/from-an-array-of-objects-extract-value-of-a-property-as-array

Same with the suggested solution here: How do i render an array of object in react

And sure enough, when I try to use the FCC solution:
<p>{props.barData.map(eachObj => Object.keys(eachObj))}</p>

I get this error message:
TypeError: Cannot read property 'map' of undefined

This makes sense since the first error already told me to not treat this like an array.

Help!

(Also, secondary issue: when I try to assign props to const barData and then reference that constant (in console.log or <p></p>, I get empty logs or paragraphs. What am I missing…isn’t that how we’re supposed to use props? Assign to const then use further down in child component. This is a somewhat secondary problem but would appreciate the help.))

Judging from your errors, you’re sending to the child component only the first item of the array - React can’t render objects and objects don’t have map() method.

But - when I console.log the props in the child component, I see the array (the same one that I screenshot-ed above). Can console.log return something different from what child component “sees”…?

It would be better if you post your code on codesandbox or codepen.

1 Like

Here, thanks to your destructuring, props.barData === barData. If they appear to be different, something very weird is going on.

Based on the error message, it looks like it’s not — it’s an object with the stated keys (presumably the first item of that array, i.e. whateverYourArrayVarIsCalled[0]).

Overall, I’m not exactly sure what you’re trying to do. Are you trying to achieve something like this?

https://codepen.io/lionel-rowe/pen/BgNLJV

1 Like

Thanks @lionel-rowe. I think that is closer to what I need. However, when I tried to implement it in my own code, I got more errors. Rather than continue describing what I am seeing, I want to move my code to CodeSandBox and just show it to everyone. (As also suggested by @jenovs) . However, when it rains, it pours and now I am having issues with CodeSandBox. :sob:

All to say, I am at my day job at the moment but will work on getting the code up on CodeSandBox as soon as I can and then be back to share the link with y’all.

Thank you!

@lionel-rowe @jenovs - I have uploaded my code: https://codesandbox.io/s/my-app-nrkqn?fontsize=14

I am trying to follow one suggested solution, at least up to the point where I am reading the data in successfully and rendering a <p></p> for each member of array. Not worrying about the bar chart for now.

However, I continue to get the error: Cannot read property 'map' of undefined

In readData.jsx you should return allHHData from countAllHHData function instead of setting state (Line 140)

I made those changes. And the data is still being passed down to child component. However, the x-axis gets filled with (seemingly arbitrary numbers) and the y-axis is set to NaN.

I also went ahead and put the raw data in directly to the JSX element, <VictoryBar/> just to make sure it was working and it looks like it is.

Updated code: https://codesandbox.io/s/github/SabahatPK/my-app

I am posting this to Victory support forum too.

So it turns out that the main problem was that when the page FIRST loaded, the data was not there (b/c it was still being loaded) and so code was trying to evaluate first, second, third etc element of an array that did not yet exist. I set default values in parent component’s this.state method and that fixed the problem of `Cannot read property ‘map’ of undefined. Once that was fixed, I went ahead with pulling out the data that I needed.

Here is that code:

const BarChart = props => {
  const firstElement = props.barData[0];  
  const { LEASED, RENTED, NA, GIVEN_BY_GOVERNMENT } = firstElement;
  const ownBarChart = [
    { x: "LEASED", y: LEASED },
    { x: "RENTED", y: RENTED },
    { x: "NA", y: NA },
    { x: "GIVEN_BY_GOVERNMENT", y: GIVEN_BY_GOVERNMENT }
  ];

//Repeat above for **each** element of props.barData

Then use the resulting data as prop in JSX element:
<VictoryBar data={ownBarChart} horizontal={true} />

The code can probably do with some refactoring but for now, I’m sticking with what I have and moving on.

Thanks to all who tried to help me!!