简体   繁体   中英

How to display JSON data inside render as table in React

I am using an API which returns JSON of various different key-value pairs. I am trying to display them inside of render() as a table of 2 columns, key and value, with object keys and values in them, respectively.

  1. The API in fetchBasicDetails() is POST which takes default this.state values as input and returns the JSON output.
  2. The JSON Output object is then stored to birth_details property of this.state using setState method.
  3. Then, I tried to show the object data in <table> tags using forEach and Object.keys, which shows nothing at all.

Any help is appreciated. Thank you.

export default class HoroscopeReport extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      day: 11,
      month: 2,
      year: 2019,
      hours: 12,
      minutes: 59,
      tzone: 5.5,
      lat: 19.22,
      lon: 25.2,
      birth_details:{}
    };
  }

  handleSubmit = event => {
    event.preventDefault();
    //console.log("Received user submitted data"+JSON.stringify(this.state))
    this.fetchBasicDetails();
  };

  fetchBasicDetails() {
        let myHeaders = new Headers();
        myHeaders.append("Content-Type", "application/x-www-form-urlencoded");
        myHeaders.append("Authorization", "Basic XXXXXXXXXXXXXXX");

        let urlencoded = new URLSearchParams();
        urlencoded.append("day", this.state.day);
        urlencoded.append("month", this.state.month);
        urlencoded.append("year", this.state.year);
        urlencoded.append("hour", this.state.hours);
        urlencoded.append("min", this.state.minutes);
        urlencoded.append("lat", this.state.lat);
        urlencoded.append("lon", this.state.lon);
        urlencoded.append("tzone", this.state.tzone);

        let requestOptions = {
          method: 'POST',
          headers: myHeaders,
          body: urlencoded,
          redirect: 'follow'
        };

        fetch("https://json.astrologyapi.com/v1/birth_details", requestOptions)
          .then(response => response.text())
          .then(result => {
            this.setState({ birth_details: result });
          })
          .catch(error => console.log('error', error));
       }

  render() {

    return (
      <div>
{/* FORM SUBMITTION CODE HERE */}
              <h2>Output:-</h2>
              <table border={2} cellPadding={5}>
                <thead>
                  <tr>
                    <td>Key</td>
                    <td>Value</td>
                  </tr>
                </thead>
                <tbody>
                  Object.keys(this.birth_details).forEach(function (element) {
                  return <tr><td>element</td><td>this.birth_details[element]</td></tr>;
                  });
                </tbody>
              </table>
      </div>
    );
  }
}

For reference, This is the output of JSON:-

{"year":2019,"month":2,"day":11,"hour":12,"minute":59,"latitude":19.22,"longitude":25.2,"timezone":5.5,"gender":" ","name":" ","seconds":0,"ayanamsha":24.124044280610406,"sunrise":"10:19:50","sunset":"21:47:13"}

Usually rendering elements based on an array in React is handled with map() instead of forEach() . The reason is with map() you can manipulate each elements meanwhile iteration and return a completely fit JSX syntax for render method. In the same time forEach() does not return anything, only undefined .

I guess you can try the following:

render() {
    return (
      <div>
        <h2>Output:-</h2>
        <table border={2} cellPadding={5}>
           <thead>
              <tr>
                <td>Key</td>
                <td>Value</td>
              </tr>
           </thead>
           <tbody>
              {
                  this.state.birth_details && 
                  Object.keys(this.state.birth_details).map(function (element) {
                     return <tr>
                       <td>{element}</td>
                       <td>{this.state.birth_details[element]}</td>
                     </tr>;
                  });
              }
           </tbody>
        </table>
      </div>
    );
}

I hope that helps!

Remember that you need to use curly braces in JSX to indicate that you want to render the value, not the code as text as-is.

You'll also want to use map instead of forEach . map is used for transforming an array to something else (we're taking a list of strings and mapping them into React elements), whereas forEach is used to just do something with each element and not return anything.

Additionally, you probably meant this.state.birth_details instead of this.birth_details >

<tbody>
{
  Object.keys(this.state.birth_details).map(function (element) {
    return (
      <tr key={element}>
        <td>{element}</td>
        <td>{this.state.birth_details[element]}</td>
      </tr>
    );
  })
}
</tbody>

I've also set the key on the returned element. Read more about lists and keys in React here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM