2

I am trying to render a simple HTML table to the screen using the following code:

import { useEffect, useState } from "react";
import "./App.css";
import { getAllBooks } from "./services/bookService";

function App() {
  const [books, setBooks] = useState([]);

  useEffect(() => {
    const loadBooks = async () => {
      try {
        const response = await getAllBooks();
        console.log(response.data.books);
        setBooks(response.data.books);
      } catch (error) {
        console.log(error);
      }
    };
    loadBooks();
  }, []);

  return (
    <div className="container">
      <h1>Simple Inventory Table</h1>
      <table>
        <thead>
          <tr>
            <th></th>
            {Object.keys(books[0]).map((item) => {
              return <th key={item}>{item}</th>;
            })}
          </tr>
        </thead>
        
      </table>
    </div>
  );
}

export default App;

The array of books I get looks like this :

const books = [
  {
    id: 1,
    Title: "Book One",
    Stock: 4,
    ISBN: "9874223457654",
    ImageURL: null,
    Pages: 281,
    createdAt: "2021-04-30T12:57:52.000Z",
    updatedAt: "2021-04-30T13:43:07.000Z",
    AuthorId: 1,
    GenreId: 2
},
  {
    id: 2,
    Title: "Book Two",
    Stock: 5,
    ISBN: "9825324716432",
    ImageURL: null,
    Pages: 231,
    createdAt: "2021-04-30T12:57:52.000Z",
    updatedAt: "2021-04-30T12:57:52.000Z",
    AuthorId: 3,
    GenreId: 6
}
];

But instead of a row of columns, I get the error: TypeError: Cannot convert undefined or null to object.

This is confusing to me because I have tried getting keys from the output array using Object.keys(books[0]) and it worked, Link to JS Bin. Can someone help me out with this?

1
  • On initial render books[0] is undefined as you set the initial state to be [] Commented May 4, 2021 at 13:44

2 Answers 2

2

Because the data would not be loaded at the time of rendering. Which will leads to an exception wile trying to access books[0]

Write a condition like this,

{books.length>0&&
 <tr>
        <th></th>
        {Object.keys(books[0]).map((item) => {
          return <th key={item}>{item}</th>;
        })}
      </tr>
}
Sign up to request clarification or add additional context in comments.

Comments

0

Export the books array from booksService.js to display all the keys

import { useEffect, useState } from "react";
import { getAllBooks } from "./bookService";

function App() {
  const [books, setBooks] = useState([]);

  useEffect(() => {
    const loadBooks = async () => {
      try {
        const response = await getAllBooks();
        console.log(response);
        setBooks(response);
      } catch (error) {
        console.log(error);
      }
    };
    loadBooks();
  }, []);

  return (
    <div className="container">
      <h1>Simple Inventory Table</h1>
      <table>
        <thead>
          {books.length > 0 && (
            <tr>
              <th></th>
              {Object.keys(books[0]).map((item) => {
                return <th key={item}>{item}</th>;
              })}
            </tr>
          )}
        </thead>
      </table>
    </div>
  );
}

export default App;

The bookService.js looks like this:

    const books = [
  {
    id: 1,
    Title: "Book One",
    Stock: 4,
    ISBN: "9874223457654",
    ImageURL: null,
    Pages: 281,
    createdAt: "2021-04-30T12:57:52.000Z",
    updatedAt: "2021-04-30T13:43:07.000Z",
    AuthorId: 1,
    GenreId: 2
  },
  {
    id: 2,
    Title: "Book Two",
    Stock: 5,
    ISBN: "9825324716432",
    ImageURL: null,
    Pages: 231,
    createdAt: "2021-04-30T12:57:52.000Z",
    updatedAt: "2021-04-30T12:57:52.000Z",
    AuthorId: 3,
    GenreId: 6
  }
];
async function getAllBooks() {
  return books;
}
module.exports = {
  getAllBooks
};

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.