0

I have a React Component that I am trying to display data in using the Object.keys() method and then trying to iterate through the data using .map().

Here is is how redux-logger is printing my data out:

body: {data: [0: {
 attributes: {
    name: "Text Widget Name",
    category: "PreBuild",
    description: "Text Widget Description",
    "chart-type": "text_widget"
 },
 type: "widget-templates"
}]}

What I am trying to do is iterate through a number of these. Here is my react component.

import PropTypes from "prop-types";
import React from "react";

class TextWidget extends React.Component { 
  render() {
    const {
      data
    } = this.props;
    const textData = data;
    const textWidgets = Object.keys(textData[0] || [])    
    .map(key => {
      return (
        <div key={key.id} className="tile-head">
          <div className="title-head-content">
            <h3>{key.attributes.name}</h3>
            {key.attributes.description}
          </div>
        </div>
      );
    });
     return (
        <div
          data={textData}
        >
          {textWidgets}
        </div>
     )
  }
}

TextWidget.propTypes = {
  data: PropTypes.array
};

export default TextWidget;
I am getting an error message say key.attributes.name is undefined.

0

4 Answers 4

1

Object.keys(textData[0]) will give you the object

{
    attributes: {
      name: "Text Widget Name",
      category: "PreBuild",
      description: "Text Widget Description",
      "chart-type": "text_widget"
    },
    type: "widget-templates"
  }

And during the iteration key will be attributes and type in your example.

Object.keys((textData[0] && textData[0].attributes) || [])    
    .map(key => {
      return (
        <div key={key.id} className="tile-head">
          <div className="title-head-content">
            <h3>{key.name}</h3>
            {key.description}
          </div>
        </div>
      );
    });

Should do. Also note that key does not have the id property.

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

Comments

1

Since your data is an array, instead of using Object.keys you would directly map over the data to render it like

const textWidgets = (textData || []).map(key => {
  return (
    <div key={key.id} className="tile-head">
      <div className="title-head-content">
        <h3>{key.attributes.name}</h3>
        {key.attributes.description}
      </div>
    </div>
  );
});
 return (
    <div
      data={textData}
    >
      {textWidgets}
    </div>
 )
}

Comments

0

It's because Object.keys(textData[0] || []) returns two top level properties.

key = attributes
key = type

const data =  [{
 attributes: {
    name: "Text Widget Name",
    category: "PreBuild",
    description: "Text Widget Description",
    "chart-type": "text_widget"
 },
 type: "widget-templates"
}];

const textData = data;
const textWidgets = Object.keys(textData[0] || [])    
    .map(key => console.log(`key = ${key}`));

You need to go one level deeper and specify .attributes.

const textWidgets = Object.keys(textData[0].attributes || [])

Comments

0

Object.keys(textData[0]) has value

["attributes", "type"]

To render the data, you have to run map on textData directly.

In your case it would be:

const textWidgets = textData.map((key, index) => {
    return (
        <div key={index} className="tile-head">
          <div className="title-head-content">
            <h3>{key.attributes.name}</h3>
            {key.attributes.description}
          </div>
        </div>
    )
});

Comments

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.