0

I'm creating a full stack MERN stack app, my front end is getting passed down the categories prop which is the model that i'm referencing to create a new Item, which is the model i'm trying to create on.

I'm getting a 400 error when I use the form to add new data. I'm new to the MERN stack so i'm not sure what exactly I'm missing when I send the data to my server. I'm guessing the issue is in my controller function, I just can not figure out how to add that reference on when I send the request to my server. Any help would be greatly appreciated

Error when I add an item, console logged the productData

Form component for adding Item


export default function AddProductForm({addProduct, categories}) {
    const [newProduct, setNewProduct] = useState({
      name: "",
      images: [],
      category: {categories},
      price: 0,
      description: ""
    });
   
    function handleChange (evt) {
      setNewProduct({...newProduct, [evt.target.name]: evt.target.value });
    }

    async function handleAddProduct(evt) {
        evt.preventDefault();
        addProduct(newProduct);
        setNewProduct({
            name: "",
            images: [],
            category: {categories},
            price: 0,
            description: ""
          });
      }
  
    return (
      <>
        <h1>Add New Product</h1>
        <form onSubmit={handleAddProduct}>
        <label>Name</label>
          <input
              name="name"
              type="text"
              value={newProduct.name}
              onChange={handleChange}
              required 
          />
        <label>images</label>
          <input
              name="images"
              type="text"
              value={newProduct.images}
              onChange={handleChange}
              required 
          />
        <label>category</label>
          <select 
              name="category" 
              value={newProduct.category}
              onChange={handleChange}>
            {categories.map ((cat, idx) => (
              <option key={idx} value={cat}>{cat}</option>
            ))}
          </select>
        <label>Price</label>
          <input
              name="price"
              type="number"
              value={newProduct.price}
              onChange={handleChange}
              required 
          />
        <label>Description</label>
          <input
              name="description"
              type="text"
              value={newProduct.description}
              onChange={handleChange}
              required 
          />
          <button type="submit">Add Product</button>
        </form>
      </>
    );
  }

Page where Form component lives



export default function AdminPage({categories}) {
    const [allProducts, setAllProducts] = useState([]);
    const [allOrders, setAllOrders] = useState([]);


    useEffect(function() {
        async function getProducts() {
          const items = await itemsAPI.getAll();
          setAllProducts(items);
        }
        getProducts();

        async function getOrders() {
            const orders = await ordersAPI.getAllActiveOrders();
            setAllOrders(orders)
        }
        getOrders();
      }, []);
  
    async function updateOrder(orderData){
        console.log(orderData)
        const updatedOrder = await ordersAPI.updateOrder(orderData);
        setAllOrders([...allOrders, updatedOrder]);
    }

    async function addProduct(productData) {
        console.log(productData)
        const newProduct = await itemsAPI.createItem(productData);
        setAllProducts([...allProducts, newProduct]);
    }

    async function deleteProduct(itemId) {
        const products = await itemsAPI.removeItem(itemId);
        setAllProducts(products);
        window.location.reload(false);
    }

    return (
        <div className="admin-page">
            <h1>Admin Page</h1>
            <h2>All Available Products </h2>
            <div className="admin-products">
                {allProducts.map((product, idx) => (
                    <div key={idx}>{product.name}<br></br> 
                        <img src={`${product.images[0]}`} alt=""/><br></br> 
                        {/* <button>Edit</button> */}
                        <button onClick={() => deleteProduct(product._id)}>Delete Item</button>
                    </div>
                ))}
            </div>
            <AddProductForm addProduct={addProduct} categories={categories} />
            <h1>ACTIVE ORDERS</h1>
            <div className="orders">
                {allOrders.map((order, idx) => (
                        <div key={idx} className="order-info">
                            Order ID: {order.orderId}<br></br>
                            Ordered on: {new Date(order.updatedAt).toLocaleDateString()}<br></br>
                            Order Total: ${order.orderTotal}
                            {order.shipment.map((info, idx) => (
                                <div key={idx} className="shipment-info">
                                    <h3>Ship to:</h3>
                                    <p>
                                        {info.name}<br></br> 
                                        {info.address}<br></br> 
                                        {info.city},&nbsp;
                                        {info.state}&nbsp;
                                        {info.zip}
                                    </p>
                                </div>
                            ))}
                            <UpdateOrderForm updateOrder={updateOrder}/>
                        </div>
                    ))}
            </div>
        </div>
    );
}

Item model (what I'm trying to create a new instance of)


const Schema = require('mongoose').Schema;

const itemSchema = new Schema({
    name: { type: String, required: true },
    images: [{ type: String, required: true }],
    category: {type: Schema.Types.ObjectId, ref: 'Category'},
    price: { type: Number, required: true },
    description: { type: String }
  }, {
    timestamps: true
  });
  
  module.exports = itemSchema;
  

category model (referenced model)


const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const categorySchema = new Schema({
  name: { type: String, required: true },
  sortOrder: Number
}, {
  timestamps: true
});

module.exports = mongoose.model('Category', categorySchema);

controller for creating item


async function create(req, res) {
  try {
    const item = await Item.create(req.body);
    res.json(item);
  } catch (err) {
    res.status(400).json(err);
  }
}

api call to route



export async function createItem(productData) {
  return sendRequest(`${BASE_URL}/new`, 'POST', productData)
}

Shea Shea
  • 11
  • 1

0 Answers0