Abubakar Oluyinka
Abubakar Oluyinka

Reputation: 351

TypeError: Cannot read properties of undefined (reading 'name')

I am trying to use bootstrap modal to display each item on a table when clicked on the view button. I initially did it in a single file and it's but now I tried to separate the modal from the list of items both which means I have two files for them now and I am getting this error: TypeError: Cannot read properties of undefined (reading 'name')

Below is my code: ModalPractice.js

import React, {useState} from 'react';
import { Table } from 'react-bootstrap';
import 'bootstrap/dist/css/bootstrap.min.css';
import { DetailModal } from './DetailModal';

const ModalPractice = () => {
  const [show, setShow] = useState(false);

  const [selectedItem, setSelectedItem] = useState({});

  const handleClose = () => {
    setShow(false);
    setSelectedItem({});
  };

  const handleShow = (e, item) => {
    setShow(true);
    setSelectedItem(item);
  };

  const food = [
    {
      id: 1,
      name: 'rice',
      category: 'grain',
      image: 'images/rice.jpg',
    },
    {
      id: 2,
      name: 'beans',
      category: 'grain and protein',
      image: 'images/beans.jpg',
    },
    {
      id: 3,
      name: 'amala',
      category: 'swallow',
      image: 'images/amala.jpg',
    },
    {
      id: 4,
      name: 'Oat',
      category: 'cereals',
      image: 'images/oat.jpg',
    },
    {
      id: 5,
      name: 'coke',
      category: 'soft drink',
      image: 'images/coke.jpg',
    },
    {
      id: 6,
      name: 'banana',
      category: 'fruit',
      image: 'images/banana.jpg',
    },
    {
      id: 7,
      name: 'okra',
      category: 'vegetable',
      image: 'images/okra.jpg',
    },
    {
      id: 8,
      name: 'yam',
      category: 'tuber',
      image: 'images/yam.jpg',
    },
    {
      id: 9,
      name: 'palm oil',
      category: 'fat',
      image: 'images/palmoil.jpg',
    },
    {
      id: 10,
      name: 'orange',
      category: 'fruit',
      image: 'images/orange.jpg',
    },
  ];

  return (
    <div>
      {/* <Modal show={show} onHide={handleClose}>
        <Modal.Header closeButton>
          <Modal.Title>{selectedItem.name}</Modal.Title>
        </Modal.Header>
        <Modal.Body>{selectedItem.category}</Modal.Body>
        <Modal.Footer>
          <Button variant='secondary' onClick={handleClose}>
            Close
          </Button>
          <Button variant='primary' onClick={handleClose}>
            Save Changes
          </Button>
        </Modal.Footer>
      </Modal> */}

      <Table striped bordered hover>
        <thead>
          <tr>
            <th>#</th>
            <th>Food Name</th>
            <th>Food Category</th>
            <th>Image</th>
          </tr>
        </thead>
        <tbody>
          {food.map((list) => (
            <tr className='align-middle' key={list.id}>
              <td>{list.id}</td>
              <td>{list.name}</td>
              <td>{list.category}</td>
              <td>
                <img alt='' src={list.image} width='100' height='100' />
              </td>
              <td>
                <DetailModal
                  id={list.id}
                  name={list.name}
                  category={list.category}
                  handleShow={handleShow}
                  handleClose={handleClose}
                  show={show}
                  selectedItem={selectedItem}
                />
              </td>
            </tr>
          ))}
        </tbody>
      </Table>
    </div>
  );
};

export default ModalPractice;

DetailModal.js

import React from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import { Button, Modal } from 'react-bootstrap';

export const DetailModal = (props) => {
  const {selectedItem, show, handleClose, handleShow, list} = props
  return (
    <div>
      <Modal show={show} onHide={handleClose}>
        <Modal.Header closeButton>
          <Modal.Title>{selectedItem.name}</Modal.Title>
        </Modal.Header>
        <Modal.Body>{selectedItem.category}</Modal.Body>
        <Modal.Footer>
          <Button variant='secondary' onClick={handleClose}>
            Close
          </Button>
          <Button variant='primary' onClick={handleClose}>
            Save Changes
          </Button>
        </Modal.Footer>
      </Modal>
      <Button variant='primary' onClick={(e) => handleShow(e, list)}>
        Detail
      </Button>
      {console.log(props)}
    </div>
  );
};

Upvotes: 1

Views: 19950

Answers (1)

Bob David
Bob David

Reputation: 51

Its showing undefined because you have not passed a list prop to the DetailModal

its should be like this

ModalPractice.js

import React, {useState} from 'react';
import { Table } from 'react-bootstrap';
import 'bootstrap/dist/css/bootstrap.min.css';
import { DetailModal } from './DetailModal';

const ModalPractice = () => {
  const [show, setShow] = useState(false);

  const [selectedItem, setSelectedItem] = useState({});

  const handleClose = () => {
    setShow(false);
    setSelectedItem({});
  };

  const handleShow = (e, item) => {
    setShow(true);
    setSelectedItem(item);
  };

  const food = [
    {
      id: 1,
      name: 'rice',
      category: 'grain',
      image: 'images/rice.jpg',
    },
    {
      id: 2,
      name: 'beans',
      category: 'grain and protein',
      image: 'images/beans.jpg',
    },
    {
      id: 3,
      name: 'amala',
      category: 'swallow',
      image: 'images/amala.jpg',
    },
    {
      id: 4,
      name: 'Oat',
      category: 'cereals',
      image: 'images/oat.jpg',
    },
    {
      id: 5,
      name: 'coke',
      category: 'soft drink',
      image: 'images/coke.jpg',
    },
    {
      id: 6,
      name: 'banana',
      category: 'fruit',
      image: 'images/banana.jpg',
    },
    {
      id: 7,
      name: 'okra',
      category: 'vegetable',
      image: 'images/okra.jpg',
    },
    {
      id: 8,
      name: 'yam',
      category: 'tuber',
      image: 'images/yam.jpg',
    },
    {
      id: 9,
      name: 'palm oil',
      category: 'fat',
      image: 'images/palmoil.jpg',
    },
    {
      id: 10,
      name: 'orange',
      category: 'fruit',
      image: 'images/orange.jpg',
    },
  ];

  return (
    <div>
      {/* <Modal show={show} onHide={handleClose}>
        <Modal.Header closeButton>
          <Modal.Title>{selectedItem.name}</Modal.Title>
        </Modal.Header>
        <Modal.Body>{selectedItem.category}</Modal.Body>
        <Modal.Footer>
          <Button variant='secondary' onClick={handleClose}>
            Close
          </Button>
          <Button variant='primary' onClick={handleClose}>
            Save Changes
          </Button>
        </Modal.Footer>
      </Modal> */}

      <Table striped bordered hover>
        <thead>
          <tr>
            <th>#</th>
            <th>Food Name</th>
            <th>Food Category</th>
            <th>Image</th>
          </tr>
        </thead>
        <tbody>
          {food.map((list) => (
            <tr className='align-middle' key={list.id}>
              <td>{list.id}</td>
              <td>{list.name}</td>
              <td>{list.category}</td>
              <td>
                <img alt='' src={list.image} width='100' height='100' />
              </td>
              <td>
                <DetailModal
                  id={list.id}
                  name={list.name}
                  category={list.category}
                  handleShow={handleShow}
                  handleClose={handleClose}
                  show={show}
                  list={list}
                  selectedItem={selectedItem}
                />
              </td>
            </tr>
          ))}
        </tbody>
      </Table>
    </div>
  );
};

export default ModalPractice;

Upvotes: 1

Related Questions