0

The intention is to choose topping, base and size and then once click 'Submit', pizza should appear on the top of the table, above select drop downs.

import React, { useState, useEffect } from 'react'
import { Container, Table } from 'reactstrap'
import AppNavbar from './AppNavbar'
import newOrderColumnsData from './columns/NewOrderColumnsData'

export default function NewOrder() {

  const [error, setError] = useState('')
  const [toppings, setToppings] = useState([])
  const [sizes, setSizes] = useState([])
  const [bases, setBases] = useState([])
  const [topping, setTopping] = useState('')
  const [base, setBase] = useState('')
  const [size, setSize] = useState('')
  const [pizzaList, setPizzaList] = useState([])

  const addPizza = () => {
    const newPizza = {
      toppingId: topping,
      pizzaSize: size,
      pizzaBase: base,
    };

    const newPizzas = [...pizzaList, newPizza];

    setPizzaList(newPizzas);
    setTopping('');
    setBase('');
    setSize('');
  }

  useEffect(() => {
    fetch("/pizza/toppings")
      .then(response => response.json())
      .then(data => setToppings(data))
      .catch((error) => setError(error.message))

    fetch("/pizza/bases")
      .then(response => response.json())
      .then(data => setBases(data))
      .catch((error) => setError(error.message))

    fetch("/pizza/sizes")
      .then(response => response.json())
      .then(data => setSizes(data))
      .catch((error) => setError(error.message))
  }, [])


    return (
        <div>
          <AppNavbar />
          <Container fluid>
            <h1 className="row justify-content-center">Create your order:</h1>
            <Table bordered hover>
              <thead>
                <tr>
                  {newOrderColumnsData.map((column) => (
                    <th key={column.key} width="25%">
                      {column.label}
                    </th>
                   ))}
                </tr>
              </thead>
      <tbody>
          {pizzaList.map((pizza) => (
            <tr>
              <td>{pizza.toppingId}</td>
              <td>{pizza.pizzaSize.pizzaSizeId}</td>
              <td>{pizza.pizzaBase.pizzaBaseId}</td>
            </tr>
          ))}
        <tr>
          <td>
            <select onChange={(event) => setTopping(event.target.value)}>
              {toppings.map((topping) => {return <option key={topping.toppingId} value={topping.toppingId}>{topping.toppingName}</option>})}
            </select>
          </td>
          <td>
            <select onChange={(event) => setSize(event.target.value)}>
              {sizes.map((size) => {return <option key={size.pizzaSizeId} value={size}>{size.pizzaSize}</option>})}
            </select>
          </td>
          <td>
            <select onChange={(event) => setBase(event.target.value)}>
              {bases.map((base) => {return <option key={base.pizzaBaseId} value={base}>{base.pizzaBaseName}</option>})}
            </select>
          </td>
        </tr>
      </tbody>
            </Table>
            <button onClick={() => addPizza()}>
      Submit
    </button>
        </Container>
    </div>
)
}

This code works, however i need to be able to save order in the database, for which i need to be passing toppingId, baseId and sizeId to request body. Is it possible to return object as value from or what would be the correct approach here?

UPD: Changed addPizza function like this:

const addPizza = () => {
  const topping = toppings.find((topping) => topping.toppingId == toppingId);
  const size = sizes.find((size) => size.pizzaSizeId == sizeId);
  const base = bases.find((base) => base.pizzaBaseId == baseId);

  const newPizza = {
    topping: topping,
    pizzaSize: size,
    pizzaBase: base,
  };

  setPizzaList(pizzaList => [...pizzaList, newPizza]);
  setToppingId('');
  setBaseId('');
  setSizeId('');
}

For some reason newPizza get created correctly, but pizzaList is always empty.

2
  • I didn't understand your question. You want to call your API with toppingId, baseId and sizeId ? What do you mean by "return object as value from" ? Commented Nov 24, 2022 at 7:55
  • So for example topping contains id and name, when i select it from dropdown, it should be added to of pizza, not only id. Same for base and size Commented Nov 24, 2022 at 8:53

1 Answer 1

1

You should search in your toppings or bases or sizes with id and then set your pizza state like this:

import React, { useState, useEffect } from 'react'
import { Container, Table } from 'reactstrap'
import AppNavbar from './AppNavbar'
import newOrderColumnsData from './columns/NewOrderColumnsData'

export default function NewOrder() {

  const [error, setError] = useState('')
  const [toppings, setToppings] = useState([]);
  const [sizes, setSizes] = useState([]);
  const [bases, setBases] = useState([]);
  const [toppingId, setToppingId] = useState('');
  const [baseId, setBaseId] = useState('');
  const [sizeId, setSizeId] = useState('');
  const [pizzaList, setPizzaList] = useState([]);

  const addPizza = () => {
    const topping = toppings.filter((topping) => tppping.toppingId === toppingId);
    const size = sizes.filter((size) => size.pizzaSizeId === sizeId);
    const base = bases.filter((base) => base.pizzaBaseId === baseId);
    const newPizza = {
      topping: topping,
      pizzaSize: size,
      pizzaBase: base,
    };

    const newPizzas = [...pizzaList, newPizza];

    setPizzaList(newPizzas);
    setTopping('');
    setBase('');
    setSize('');
  }

  useEffect(() => {
    fetch("/pizza/toppings")
      .then(response => response.json())
      .then(data => setToppings(data))
      .catch((error) => setError(error.message))

    fetch("/pizza/bases")
      .then(response => response.json())
      .then(data => setBases(data))
      .catch((error) => setError(error.message))

    fetch("/pizza/sizes")
      .then(response => response.json())
      .then(data => setSizes(data))
      .catch((error) => setError(error.message))
  }, [])


  return (
      <div>
        <AppNavbar />
          <Container fluid>
            <h1 className="row justify-content-center">Create your order:</h1>
            <Table bordered hover>
              <thead>
                <tr>
                  {newOrderColumnsData.map((column) => (
                    <th key={column.key} width="25%">
                      {column.label}
                    </th>
                   ))}
                </tr>
              </thead>
      <tbody>
          {pizzaList.map((pizza) => (
            <tr>
              <td>{pizza.topping.toppingName}</td>
              <td>{pizza.size.pizzaSize}</td>
              <td>{pizza.base.pizzaBaseName}</td>
            </tr>
          ))}
        <tr>
          <td>
            <select onChange={(event) => setTopping(event.target.value)}>
              {toppings.map((topping) => {return <option key={topping.toppingId} value={topping.toppingId}>{topping.toppingName}</option>})}
            </select>
          </td>
          <td>
            <select onChange={(event) => setSize(event.target.value)}>
              {sizes.map((size) => {return <option key={size.pizzaSizeId} value={size.pizzaSizeId}>{size.pizzaSize}</option>})}
            </select>
          </td>
          <td>
            <select onChange={(event) => setBase(event.target.value)}>
              {bases.map((base) => {return <option key={base.pizzaBaseId} value={base.pizzaBaseId}>{base.pizzaBaseName}</option>})}
            </select>
          </td>
        </tr>
      </tbody>
            </Table>
            <button onClick={() => addPizza()}>
      Submit
    </button>
        </Container>
    </div>
  )
}
Sign up to request clarification or add additional context in comments.

2 Comments

I put updates on the initial post regarding your suggestions
When you log pizzaList, it shows an empty array ?

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.