title: React-Redux Bad Request Error (404) But Still Saves Data From Schema
body: <p>I'm getting a <strong>status(400)</strong> on a <strong>post request</strong> for some <strong>nested</strong> inventory data. <strong>The request fulfills</strong> by saving the data but responds with a 400. It also doesn't fulfill the <strong>.then()</strong> promise so I can't save the list back to the state. I have no idea why it's saving the data to MongoDB, yet it says it's a bad request.</p>
  <p>I have a feeling the issue <strong>stems 3 issues</strong>:</p>
  <ol>
  <li>The Schema <strong>structure</strong>,</li>
  <li>The route <strong>callbacks</strong>,</li>
  <li>The data from the component being passed in isn't <strong>properly
  typed</strong>.</li>
  </ol>
  <p>I tried:</p>
  <ol>
  <li>Removing the required values of the schema objects,</li>
  <li>Removing the .catch() method from the route,</li>
  </ol>
  <p>My data comes from a CSV file like this:</p>
  <p>Item,ItemDescription,ItemLocation,OnHand
  29081128,item1,loc1,24
  29119208,item2,loc2,43
  26094208,item3,loc3,4800</p>
  <p><strong>Hopefully its something simple :)</strong></p>
  <p>REACT COMPONENT:
  <div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>import React, { useState } from "react";
  import { Input, Button } from "reactstrap";
  import { postList } from "../../../redux/inventory/inventoryActions";
  import { useDispatch, useSelector } from "react-redux";
  const crypto = require("crypto");
  
  const Footer = () =&gt; {
    const inventory = useSelector((state) =&gt; state.inventory);
    const auth = useSelector((state) =&gt; state.auth);
    const dispatch = useDispatch();
    const [inputValue, setInputValue] = useState("");
    const onChange = (e) =&gt; {
      e.preventDefault();
      setInputValue(e.target.value);
    };
    const onSubmit = () =&gt; {
      const list_id = crypto.randomBytes(12).toString("hex");
      const items = inventory.preparedList.map((items) =&gt; {
        const item_id = crypto.randomBytes(12).toString("hex");
        const loc_id = crypto.randomBytes(12).toString("hex");
        const loc = items.data.ItemLocation;
        const item = {
          number: items.data.Item,
          desc: items.data.ItemDescription,
          locs: [{ loc: loc, count: 0, _id: loc_id }],
          oh: parseInt(items.data.OnHand),
          _id: item_id,
        };
        return item;
      });
      const list = {
        listName: inputValue,
        _id: list_id,
        listId: auth.user.id,
        items: items,
      };
      dispatch(postList(list));
    };
    const footerContainerStyle = {
      height: "100%",
      width: "90%",
      display: "flex",
      justifyContent: "space-evenly",
      alignItems: "center",
      flexDirection: "row",
    };
    return (
      &lt;div style={footerContainerStyle}&gt;
        &lt;Button
          color="danger"
          onClick={() =&gt; {
            setInputValue("");
          }}
        &gt;
          Reset
        &lt;/Button&gt;
        &lt;Input value={inputValue} onChange={onChange} placeholder="add name" /&gt;
        &lt;Button color="success" disabled={!inputValue} onClick={onSubmit}&gt;
          Save
        &lt;/Button&gt;
      &lt;/div&gt;
    );
  };
  export default Footer;</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"&gt;&lt;/script&gt;
  &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"&gt;&lt;/script&gt;</code></pre>
  </div>
  </div>
  </p>
  <p>ACTION FILE:</p>
  <pre class="lang-js-react-redux prettyprint-override"><code>import axios from &quot;axios&quot;;
  
  import {
    SAVE_FETCHED_LISTS,
    SAVE_POSTED_LIST,
    SAVE_PREPARED_LIST,
  } from &quot;./inventoryTypes&quot;;
  
  export const fetchLists = () =&gt; {
    return (dispatch) =&gt; {
      axios.get(&quot;/inventory/lists&quot;).then((response) =&gt; {
        dispatch({
          type: SAVE_FETCHED_LISTS,
          payload: response.data,
        });
      });
    };
  };
  
  export const postList = (list) =&gt; {
    return (dispatch) =&gt; {
      axios.post(&quot;/inventory/lists&quot;, list).then((response) =&gt; {
        console.log(response.status);
        dispatch({
          type: SAVE_POSTED_LIST,
          payload: list,
        });
      });
    };
  };
  
  export const prepareList = (list) =&gt; {
    return (dispatch) =&gt; {
      dispatch({
        type: SAVE_PREPARED_LIST,
        payload: list,
      });
    };
  };
  </code></pre>
  <p>SCHEMA:</p>
  <pre class="lang-js-mongoose prettyprint-override"><code>const mongoose = require(&quot;mongoose&quot;);
  const Schema = mongoose.Schema;
  
  const locSchema = new Schema({
    loc: { type: String, required: true },
    count: { type: Number, required: true },
    _id: { type: String, required: true },
  });
  mongoose.model(&quot;loc&quot;, locSchema);
  
  const ItemSchema = new Schema({
    number: { type: String, required: true },
    desc: { type: String, required: true },
    oh: { type: Number, required: true },
    locs: [locSchema],
    _id: { type: String, required: true },
  });
  mongoose.model(&quot;item&quot;, ItemSchema);
  
  const ListSchema = new Schema({
    listId: {
      type: String,
      required: true,
    },
    _id: {
      type: String,
      required: true,
    },
    items: [ItemSchema],
    listName: {
      type: String,
      required: true,
    },
  });
  
  module.exports = List = mongoose.model(&quot;lists&quot;, ListSchema);
  </code></pre>
  <p>ROUTER:</p>
  <pre class="lang-js-express prettyprint-override"><code>const router = require(&quot;express&quot;).Router();
  let List = require(&quot;../models/lists&quot;);
  const { authUser } = require(&quot;../middlware/auth&quot;);
  
  router.get(&quot;/lists&quot;, (req, res) =&gt; {
    List.find()
      .then((lists) =&gt; {
        res.json(lists);
      })
      .catch((err) =&gt; {
        res.status(400).json({ msg: &quot;error: &quot; + err });
      });
  });
  
  router.post(&quot;/lists&quot;, (req, res) =&gt; {
    const newList = new List({
      listName: req.body.listName,
      _id: req.body._id,
      listId: req.body.listId,
      items: req.body.items,
    });
    newList
      .save()
      .then((res) =&gt; res.json(&quot;list added&quot;))
      .catch((err) =&gt; res.status(400).json(&quot;Error: &quot; + err));
  });
  
  module.exports = router;
  </code></pre>
  <p>SERVER:</p>
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>const express = require("express");
  const cors = require("cors");
  const mongoose = require("mongoose");
  const path = require("path");
  const passport = require("passport");
  
  const db = require("./config/keys").mongoURI;
  
  const app = express();
  const port = process.env.PORT || 5000;
  
  app.use(cors());
  app.use(express.json());
  
  mongoose.connect(db, {
    useNewUrlParser: true,
    useCreateIndex: true,
    useUnifiedTopology: true,
  });
  const connection = mongoose.connection;
  connection.once("open", () =&gt; {
    console.log("MongoDB database connection established successfully");
  });
  
  const inventoryRouter = require("./routes/inventory.js");
  const usersRouter = require("./routes/users.js");
  
  app.use(passport.initialize());
  require("./config/passport")(passport);
  
  app.use("/inventory", inventoryRouter);
  app.use("/users", usersRouter);
  
  if (process.env.NODE_ENV === "production") {
    app.use(express.static("client/build"));
    app.get("*", (req, res) =&gt; {
      res.sendFile(path.resolve(__dirname, "client", "build", "index.html"));
    });
  }
  
  app.listen(port, () =&gt; {
    console.log(`Server is running on port: ${port}`);
  });</code></pre>
  </div>
  </div>
  </p>