0

I've been trying for a while now, with no luck on trying to get it to where a user clicks on a table item that it brings up a window with the information on what they clicked. I have a JSON file and would like it to read the information from the file instead of the actual file page.

Here is the main app page

import './App.scss';
import list from './list.json';

import Table from 'react-bootstrap/Table';
import MyVerticallyCenteredModal from './components/modal';

function App() {

  const [modalShow, setModalShow] = useState(false);
  
  const [menu, setMenu] = useState(
    {
      food: ""
    }
  );

  const handleChange = (event) => {
    setMenu({
      food: event.target.value
    });
  }

  const [looped] = useState(
    list.map((obj, i) => {
      return (
        <tr key={i} onClick={() => {
          
          setModalShow(true);

          handleChange(obj.food)
          console.log(obj.food)
        
        }
        }>
          <td>{i + 1}</td>
          <td>{obj.food}</td>
          <td>{obj.description}</td>
          <td>${obj.price.toString()}</td>
        </tr>
      )
    })
    );
    
    // console.log(menu);

    return (
      <div className="menu-template container-lg">
      <div className="mt-5 mb-5 d-flex">
        <Table striped bordered hover>
          <thead>
            <tr>
              <th>#</th>
              <th>Meal Name</th>
              <th>Description</th>
              <th>Price</th>
            </tr>
          </thead>
          <tbody>
            {
              looped
            }
          </tbody>
        </Table>
      </div>
            <MyVerticallyCenteredModal
              food={food}
              description={description}
              price={price}
              show={modalShow}
              onHide={() => setModalShow(false)}
            />
    </div>
  );
}

export default App;

Here is the modal


import Modal from 'react-bootstrap/Modal';
import Button from 'react-bootstrap/Button';

import image from '../assets/image1.jpg';

function MyVerticallyCenteredModal(props) {
    return (
            <Modal
                {...props}
                size="lg"
                aria-labelledby="contained-modal-title-vcenter"
                centered
            >
                <Modal.Header>
                    <Modal.Title id="contained-modal-title-vcenter">
                        <img src={image} alt="..." width="100%" />
                    </Modal.Title>
                </Modal.Header>
                <Modal.Body>
                    <h4>
                        Some Tasty Food!</h4>
                    <p>
                        This is the best food you've ever eaten!
        </p>
                </Modal.Body>
                <Modal.Footer>
                    <Button onClick={props.onHide} variant="danger">Close</Button>
                </Modal.Footer>
            </Modal>
    ); 

}


export default MyVerticallyCenteredModal;```
Janez Kuhar
  • 3,705
  • 4
  • 22
  • 45
Tate
  • 31
  • 7
  • Don't store JSX in component state, you should map the data to JSX in the render return. Other than this can you expand a bit more on what isn't working for you? Is there an error? Can you try creating a *running* codesandbox for us to inspect and live debug in? – Drew Reese May 28 '21 at 06:12
  • I tried I use react-bootstrap and tried to import it into codesandbox but it wouldn't work – Tate May 29 '21 at 03:45

2 Answers2

0

In the model file. When you're exporting the component remove default. Use something like this-

export {MyVetrical....}

Lemme know if it works

0

From the first look at this, it doesn't look like you are adding an event to the handleChange() function, just passing a parameter from the obj dictionary. Also, since you are only showing a modal when there is a value in the menu, I would just use that as the indicator to show.

Here's a small sample:

  
  const [menu, setMenu] = useState(null);

  const [looped] = useState(
    list.map((obj, i) => {
      return (
        <tr key={i} onClick={() => setMenu({food: obj.food, description: obj.description, price: obj.price, <etc...>})}>
          <td>{i + 1}</td>
          <td>{obj.food}</td>
          <td>{obj.description}</td>
          <td>${obj.price.toString()}</td>
        </tr>
      )
    })
    );
    
    // console.log(menu);

    return (
      <div className="menu-template container-lg">
      <div className="mt-5 mb-5 d-flex">
        <Table striped bordered hover>
          <thead>
            <tr>
              <th>#</th>
              <th>Meal Name</th>
              <th>Description</th>
              <th>Price</th>
            </tr>
          </thead>
          <tbody>
            {
              looped
            }
          </tbody>
        </Table>
      </div>
            <MyVerticallyCenteredModal
              {...menu} /** Just spreading out the dictionary from the state */ 
              show={!!menu} // Double ! makes it a true or false
              onHide={() => setMenu(null)} // or false..
            />
    </div>
  );
}   ```



----------

Because you have now passed the props from that state, you can now use
them on the modal like this:


function MyVerticallyCenteredModal(props) {
const {food, descriptions, price} = props

console.log('view passed props')
....
}



Jayb967
  • 316
  • 3
  • 5
  • A lot of it seems to want to work except for the {menu && ...menu} part, any other alterations I could try? – Tate May 29 '21 at 03:28
  • Just remove the conditional i.e. just {...menu}, you just have to make sure that the value is actually there on your modal component you or you will get an undefined error... I have updated code to reflect this.. – Jayb967 May 30 '21 at 02:26
  • Oooh I see this worked for me! So basically needed to save the objects into the useState hook then I could just use a spread operator to bring all the objects into the modal? – Tate May 31 '21 at 17:52