2

I have problem to display nested array data that I retrieved from api call. The JSON data format is like:

[
  {
   pageNo: 1
   TotalRecordsCount: 8000,
   Items: [
   {
    id: 1,
    subject: "ACCOUNTING",
    campus: "campus A"
   },

     {
    id: 1,
    subject: "ACCOUNTING",
    campus: "campus A"
     },
  ...
  }

 ]

Edit data format:

Items: [{subject: ACCOUNTING, CAMPUS: CAMPUS A}, {subject: ACCOUNTING, campus: CAMPUS A}...]
PageNo: 1
TotalRecordCount: 8000

in JSON format.

How to access subject, campus, etc. data in ReactJS? I got the error message: Objects are not valid as a React child (found: object with keys {courseItem}).

App.js

import React, { Component } from 'react';
import axios from 'axios';

class App extends Component {
 constructor() {
 super();
 this.state ={
  courses:[]
 };
 }
 componentDidMount(){
 axios.get('myURL')
 .then(response=>{
  this.setState({
    courses:response.data
  });
  });
}
_getCourses(){
const data=this.state.courses;
const courseItem=data.map((course,index)=>(
<div>
  Page No: course.ageNo  <br />
  <div className="courseItem"><ul>
  Course: <li>ID:{course.id}
  SUBJECT:{course.subject}
  CAMPUS: {course.campus} </li>
  </ul></div>
</div>
));
render() {
const courses= this._getCourses();
return (
  <div className="App">
   <div className="courseResults">
   {courses}    
   </div>
  </div>
);
}
}
export default App;

Thanks.

2 Answers 2

2
  1. In componentDidMount you are currently setting courses to just response.data. And this is the outer array from your response. The courses array is the inner array. So, you need to set courses to response.data[0].Items. Perhaps you want to iterate over response.data array as well if you expect more than one entry there.

    componentDidMount() {
        axios.get('http://localhost:8080')
            .then(response => {
                this.setState({
                    courses: response.data[0].Items
                });
            });
    }
    
  2. In _getCourses you need to return the courseItems variable:

    _getCourses() {
        const data = this.state.courses;
        const courseItems = data.map((course, index) => (
            <div>
                Page No: course.ageNo  <br />
                <div className="courseItem"><ul>
                    Course: <li>ID:{course.id}
                        SUBJECT:{course.subject}
                        CAMPUS: {course.campus} </li>
                </ul></div>
            </div>
        ));
        return courseItems;
    }
    
  3. You have the render function inside of the _getCourses and it has to be on the same level, at the class level:

    class App extends Component {
        constructor() { ... }
    
        componentDidMount() { ... }
    
        _getCourses() { ... }
    
        render() { ... }
    }
    
Sign up to request clarification or add additional context in comments.

Comments

0
import React, { Component } from 'react';
import { render } from 'react-dom';

class App extends Component {
  constructor() {
    super();
    this.state = {
      courses: [
        {
          pageNo: 1,
          TotalRecordsCount: 8000,
          Items: [
            {
              id: 1,
              subject: "ACCOUNTING",
              campus: "campus A"
            },
            {
              id: 1,
              subject: "ACCOUNTING",
              campus: "campus A"
            }
          ]
        }
      ]
    }
  }

  _getCourses() {
    const data = this.state.courses.slice(0);
    const courseItem = data.map((course, index) => (
      <div>
        Page No: course.ageNo  <br />
        <div className="courseItem">
          <ul>
            {course.Items.map((details, index) => (
              <React.Fragment>
                <li>
                  Course:  ID:{details.id}
                </li>
                <li>
                  SUBJECT:{details.subject}
                </li>
                <li>
                  CAMPUS: {details.campus}
                </li>
              </React.Fragment>))}
          </ul>
        </div>
      </div>
    ))
    return courseItem;
  }

  render() {
    return (
      <div className="App">
        <div className="courseResults">
          {this._getCourses()}
        </div>
      </div>
    );
  }
}

render(<App />, document.getElementById('root'));

https://stackblitz.com/edit/react-mnh5ex?embed=1&file=index.js

You needed to return courseItem in the _getCourse function. Otherwise it will not render any html when you call the _getCourse in the render function.

You also need to acess Items, because Items contains the data you want to access.

    {
      id: 1,
      subject: "ACCOUNTING",
      campus: "campus A"
    },
    {
      id: 1,
      subject: "ACCOUNTING",
      campus: "campus A"
    }

7 Comments

Thank you! I got error "TypeError: this.state.courses.slice is not a function" on line const data = this.state.courses.slice(0); The console log returns data array though.
Look at my example it runs on stackblitz. Just copy it into your editor, get it working with fake data before you use axios. My guess is the data you are storing in state is not an array thats why it does not let you slice.
The code works with the fake data array but not JSON data format returned from api call.
Okay give me the link to your api
Unfortunately the API link is password protected right now. I can only have the JSON data format here.
|

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.