I am getting this in the browser console:
`xhr.js:251 POST http://localhost:325/budget 400 (Bad Request)
BudgetNew.js:30 catch AxiosError {message: 'Request failed with status code 400', name: 'AxiosError', code: 'ERR_BAD_REQUEST', config: {…}, request: XMLHttpRequest, …}`
Here is my server side code:
budget_controller:
//DEPENDENCIES
const express = require("express");
const budget = express.Router();
const budgetArray = require("../models/budget_table.js");
const { validateBudgetData } = require("../models/validations.js");
//CONFIGURATION
budget.get('/', (req, res) => {
res.json(budgetArray);
});
/* this route is triggered when a "GET" request is made to the base URL ("/budget"). It responds by sending the entire budgetArrau as a JSON in the res body - this retrieves a list of items in the budget array
*/
//with error handling:
budget.get("/:arrayIndex", (req,res) => {
if(budgetArray[req.params.arrayIndex]) {
res.json(budgetArray[req.params.arrayIndex]);
} else {
res.status(404).json({error: "Not Found"});
}
});
budget.post("/", validateBudgetData, (req, res) => {
budgetArray.push(req.body);
res.json(budgetArray[budgetArray.length - 1])
});
//DELETE with error handling
budget.delete("/:indexArray", (req, res) => {
if (budgetArray[req.params.indexArray]) {
const deletedItem = budgetArray.splice(req.params.indexArray, 1);
res.status(200).json(deletedItem);
} else {
res.status(404).json({ error: "Not Found" });
}
})
//UPDATE/change already existing data (HTTP verb PUT) with error handling
budget.put("/:arrayIndex", validateBudgetData, async (req, res) => {
if (budgetArray[req.params.arrayIndex]) {
budgetArray[req.params.arrayIndex] = req.body;
res.status(200).json(budgetArray[req.params.arrayIndex]);
} else {
res.status(404).json({ error: "Not found" })
}
});
//EXPORT
module.exports = budget;
validations:
const validateBudgetData = (req, res, next) => {
const { item_name, amount, deduction, date, category } = req.body;
if (
typeof item_name === 'string' &&
typeof amount === 'number' &&
typeof deduction === 'boolean' &&
typeof date === 'string' &&
typeof category === 'string'
) {
return next();
} else {
res.status(400).send("Invalid budget data");
}
};
//EXPORT
module.exports = { validateBudgetData };
REACT BudgetNew Component
import { useState } from "react";
import { useNavigate, Link, useParams } from "react-router-dom";
import axios from "axios";
export default function BudgetNew() {
const API = process.env.REACT_APP_API_URL;
const navigate = useNavigate();
const { index } = useParams(); //Get the index parameter from the URL
const [transaction, setTransaction] = useState({
item_name: "",
amount: 0,
date: "",
deduction: false,
category: "",
});
const handleTextChange = (e) => {
setTransaction({ ...transaction, [e.target.id]: e.target.value });
};
const handleCheckboxChange = () => {
setTransaction({ ...transaction, deduction: !transaction.deduction });
};
const addTransaction = (newTransaction) => {
axios
.post(`${API}/budget`, newTransaction)
.then(() => {
navigate("/budget");
})
.catch((c) => console.error("catch", c));
};
/* the addTransaction fxn takes 2 parameters:
// 1.the URL where the request will be sent
// 2. newTransaction, a variable that represents the data of the new transaction to be added to the server
// */
const handleSubmit = (e) => {
e.preventDefault();
addTransaction(transaction);
//call the addTransaction fxn with the transaction data and not "newTransaction" because the form data is stored in transaction from our useState fxn not "newTransaction". So, when we want to call the addTransaction fxn, we should pass the transaction data as an argument.
}
return (
<div className="Edit">
<form onSubmit={handleSubmit}>
<label htmlFor="name">Name:</label>
<input
id="item_name"
value={transaction.item_name}
type="text"
onChange={handleTextChange}
placeholder="Item name"
required
/>
<label htmlFor="amount">Amout:</label>
<input
id="amount"
value={transaction.amount}
type="number"
onChange={handleTextChange}
placeholder="Enter amount"
required
/>
<label htmlFor="deduction">Is this transaction a deduction?</label>
<p>Does this take away from total income? If yes, check the box. If no, leave box unchecked.</p>
<input
id="deduction"
value={transaction.deduction}
type="checkbox"
onChange={handleCheckboxChange}
/>
<br />
<label htmlFor="date">Date:</label>
<p>Enter as mm/dd/yyyy</p>
<input
id="date"
value={transaction.date}
type="text"
onChange={handleTextChange}
placeholder="Date of transaction"
// required
/>
<label htmlFor="category">Category: </label>
<input
id="category"
value={transaction.category}
type="text"
onChange={handleTextChange}
placeholder="What is this for?"
required
/>
<br />
<input type="submit" />
</form>
<Link to={`/budget/${index}`}>
<button>Nevermind!</button>
</Link>
</div>
);
}
I tried restarting the starting and react app. I reviewed my code. I commented out my "addTransaction" fxn in the BudgetNew component and added this code:
const requestData = {
item_name: "Cash",
amount: 100,
deduction: false,
date: "07/30/23",
category: "income"
};
axios.post(`${API}/budget`, requestData)
.then((response) => {
console.log("Success:", response.data);
})
.catch((error) => {
console.log("Error:", error.response.data);
});
This worked, which hinted the server side was not the problem, but I am still getting the error.