Noble Polygon
Noble Polygon

Reputation: 806

React mapping nested data

I'm having a problem with my React app. When I post a new project to my backend, I click the button to return me to the site dashboard where I can view a list of projects, I get the following error:

Uncaught TypeError: Cannot read property 'name' of undefined

Main.jsx

Map Function:

{props.sites.map((site) => (
 <tr key={site.id}>
 <td data-label="Project">{site.site.name}</td>
          ... //remaining code

However, if I reload the page, all the data is shown.

In React Developer Tools, if I look at how props are passed, I can see name as one of the pieces of available data.


|_sites
  |_ 0
   |_id" 22
   |_site
      |_id: 44
      |_name: "test"

However, name is nested under site which is nested under sites.

When using the .map function, I have to use the keyword site to render a list of sites. Is this causing a conflict with the keyword site that is already in my backend data structure?

    this.state = {
      sites: [],
      siteFormData: {
        name: '',
      },
   }

If so, what is the best practice to fix this?

Upvotes: 0

Views: 81

Answers (2)

Yevhen Horbunkov
Yevhen Horbunkov

Reputation: 15530

With React it is a common thing to use destructuring assignment syntax for such purposes, i.e. to avoid above confusion you may go, like:

{props.sites.map(({id,site}) => (
 <tr key={id}>
 <td data-label="Project">{site.name}</td>

Or even go a bit further, since key doesn't necessarily have to correspond to your object properties:

{props.sites.map(({site:{name}},key) => (
 <tr key={key}>
 <td data-label="Project">{name}</td>

Upvotes: 2

norbitrial
norbitrial

Reputation: 15166

From your array structure it seems that you made a mistake once you tried to access site.site.name which does not really exist. Instead it should be site.name.

Technically in the first case site.site becomes undefined which does not have a name property and that's why you got that error message.

Just correct the line as the following:

<td data-label="Project">{site.name}</td>

I hope that helps!

Upvotes: 2

Related Questions