please help me with this problem as I searched all the Internet but couldn't find the answer :(
I'm making a website using MERN Stack and I'm encounting a problem which is:
Whenever I click Update on the empty input field, my app would crash.
When I catch the error in the Axios update request, it just says Network Error.
I want to ask if there's anyway to fix this error? Maybe if the input field is empty, the Update button won't fire?
Here's my code:
// DinnerIdeas.js
import React, { useState, useEffect } from "react"
import './DinnerIdeas.css'
import Axios from "axios"
import FoodListComponent from "../FoodListComponent";
import FormComponent from "../FormComponent";
function DinnerIdeas() {
const [foodName, setFoodName] = useState('')
const [isVegetarian, setVegetarian] = useState(false)
const [priceRange, setPriceRange] = useState('$')
const [newFoodName, setNewFoodName] = useState(null)
const [foodList, setFoodList] = useState([])
// Read:
useEffect(() => {
let unmounted = false
Axios.get("http://localhost:3001/read")
.then((response) => {
if (!unmounted) {
setFoodList(response.data)
}
})
.catch(error => {
console.log(`Hey, the error is ${error}`)
return
})
return () => {
unmounted = true
}
}, [foodList])
// Create:
const addToList = () => {
Axios.post(
"http://localhost:3001/insert",
{
foodName: foodName,
isVegetarian: isVegetarian,
priceRange: priceRange,
}
)
}
// Update:
const updateFood = (id) => {
Axios.put("http://localhost:3001/update", {
id: id,
newFoodName: newFoodName,
})
.catch(error => console.log(`Hey, the error is ${error}`))
}
// Delete:
const deleteFood = (id) => {
Axios.delete(`http://localhost:3001/delete/${id}`)
}
return (
<section className="dinner-ideas">
<FormComponent
setFoodName={setFoodName}
setVegetarian={setVegetarian}
setPriceRange={setPriceRange}
addToList={addToList}
/>
<FoodListComponent
foodList={foodList}
setNewFoodName={setNewFoodName}
updateFood={updateFood}
deleteFood={deleteFood}
/>
</section>
);
}
export default DinnerIdeas;
FormComponent:
export default function FormComponent(props) {
return (
<div className="dinner container">
<h1 className="dinner--title">Dinner Ideas</h1>
<form>
<div className="form-group">
<label htmlFor="name">Food name:</label>
<input
type="text"
name="name"
placeholder="Ex: Pesto Pasta"
maxLength="50"
onChange={(event) => {props.setFoodName(event.target.value)}}
required
/>
</div>
<br />
<div className="form-group">
<label htmlFor="vegetarian"> Is this dish Vegetarian?</label>
<select
name="vegetarian"
onChange={(event) => {props.setVegetarian(event.target.value)}}
>
<option value="false">No</option>
<option value="true">Yes</option>
</select>
</div>
<br />
<div className="form-group">
<label htmlFor="price">Price range:</label>
<select
name="price"
onChange={(event) => {props.setPriceRange(event.target.value)}}
>
<option value="$">$</option>
<option value="$$">$$</option>
<option value="$$$">$$$</option>
</select>
</div>
<br />
</form>
<button
type="submit"
className="dinner--btn"
onClick={props.addToList}
>
Add to list
</button>
</div>
)
}
Server side: index.js
const express = require("express") // Set up an express server
const mongoose = require("mongoose") // Import Mongoose library
const cors = require('cors') // Import CORS to communicate with frontend
const app = express() // Initializing our express server
const DinnerModel = require('./models/Dinner')
app.use(express.json()) // Setting up Middleware
app.use(cors())
// Connect to MongoDB
mongoose.connect(
'mongodb srv://higherstates:<password>@crud.cvewg.mongodb.net/dinner_ideas?retryWrites=true&w=majority',
{
useNewUrlParser: true,
}
)
// Create:
app.post("/insert", async (req, res) => {
const foodName = req.body.foodName
const isVegetarian = req.body.isVegetarian
const priceRange = req.body.priceRange
const dinner = new DinnerModel(
{
foodName: foodName,
isVegetarian: isVegetarian,
priceRange: priceRange,
}
)
try {
await dinner.save()
res.send("data inserted")
} catch(err) {
console.log(err)
}
})
// Read:
app.get("/read", async (req, res) => {
DinnerModel.find({}, (err, result) => {
if (err) {
res.send(err)
}
res.send(result)
})
})
// Update:
app.put("/update", async (req, res) => {
const newFoodName = req.body.newFoodName
const id = req.body.id
try {
await DinnerModel.findById(id, (err, updatedFood) => {
updatedFood.foodName = newFoodName
updatedFood.save()
res.send("update")
}).clone()
} catch(err) {
console.log("The error is: " err)
}
})
app.delete("/delete/:id", async (req, res) => {
const id = req.params.id
await DinnerModel.findByIdAndRemove(id).exec()
res.send("deleted")
})
// Creating a port:
app.listen(3001, () => {
console.log("Server is up on: http://localhost:3001")
})
FoodListComponent:
export default function FoodListComponent(props) {
return (
<div className="food-list container">
<h1 className="food-list--title">Food List</h1>
<table>
<thead>
<tr>
<th className="th--name">Name</th>
<th className="th--vegetarian">Vegetarian</th>
<th className="th--price">Price</th>
<th className="th--edit">Edit</th>
<th className="th--actions">Action</th>
</tr>
</thead>
<tbody>
{props.foodList.length > 0 && props.foodList.map((val, key) => {
return (
<tr key={key}>
<td>{val.foodName}</td>
<td>
{val.isVegetarian ? <input type="checkbox" checked readOnly /> : <input type="checkbox" disabled="disabled" readOnly />}
</td>
<td>{val.priceRange}</td>
<td>
<input
name="edit"
placeholder="New food name.."
size="15"
maxLength="50"
onChange={(event) => {props.setNewFoodName(event.target.value)}}
>
</input>
</td>
<td>
<button
className="table--btn"
onClick={() => props.updateFood(val._id)}
>
Update
</button>
<button
className="table--btn"
onClick={() => props.deleteFood(val._id)}
>
❌
</button>
</td>
</tr>
)
})}
</tbody>
</table>
</div>
)
}
Mongoose Schema:
const mongoose = require('mongoose')
const DinnerSchema = new mongoose.Schema({
foodName: {
type: String,
default: true,
},
isVegetarian: {
type: Boolean,
required: true,
},
priceRange: {
type: String,
required: true,
}
})
const Dinner = mongoose.model("Dinner", DinnerSchema)
module.exports = Dinner
Here's the demonstration:
1. If I click on the **Update button** without filling in the **Edit field**, it won't do anything but the data disappears when I refresh the page. Error message in the console:
https://i.stack.imgur.com/cyAtQ.gif [Demonstrating gif]
- The app crashed and here's the error message in the server's terminal
https://i.stack.imgur.com/bgayZ.jpg [nodemon app crashed error]
Thanks everyone!
CodePudding user response:
// Update:
const updateFood = (id) => {
if(newFoodName){
Axios.put("http://localhost:3001/update", {
id: id,
newFoodName: newFoodName,
})
.catch(error => console.log(`Hey, the error is ${error}`))
}
}