#reactjs #mongodb #mongoose #axios #react-router
Вопрос:
проблема проста Я хотел бы обновить значения из массива меню, хранящегося в mongo atlas, используя интерфейс react и запрос axios
Это модель
// restaurantModel.jsx
const mongoose = require("mongoose");
const restaurantSchema = new mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
restaurantName: {
type: String,
required: true,
},
restaurantRegistrationStatus: {
type: Boolean,
},
resturanturl: {
type: String,
},
restaurantPhone: {
type: Number,
},
restaurantEmail: {
type: String,
lowercase: true,
trim: true,
unique: true,
required: true,
},
rCity: {
type: String,
},
rating: {
type: Number,
},
cuisine: {
type: Array,
},
reviews: {
type: Array,
of: new mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
reviewText: String,
user: { type: mongoose.Schema.Types.ObjectId, ref: "customer" },
}),
},
menus: {
type: Array,
of: new mongoose.Schema({
menuID: mongoose.Schema.Types.ObjectId,
menuName: String,
menuPrice: Number,
}),
},
});
module.exports = mongoose.model("restaurant", restaurantSchema);
Это код для обновления
// restaurantRoute.jsx
router.patch("/menu/:menuID", (req, res) => {
Restaurant.findOneAndUpdate(
{ "menus._id": req.params.menuID },
{
$set: {
"menus.$.menuName": req.body.menuName,
"menus.$.menuPrice": req.body.menuPrice,
},
},
{ new: true, upsert: false }
)
.then((data) => res.json(data))
.catch((err) => res.json({ "Error in updating menu": err.message }));
});
Код для отображения отдельных блюд(т. е. элементов из массива меню)
{restaurant.menus.map((dish) => {
return (
<div>
<EditDish
dish={dish}
key={dish._id}
btnName="Delete"
handleFunction={() => handleDelete(id, dish._id)}
// updateFunction={handleUpdate}
updateFunction={(e) => handleUpdate(e, dish._id)}
setMenuName={setMenuName}
setMenuPrice={setMenuPrice}
openPopup={openPopup}
handleOpenPopup={handleOpenPopup}
handleClosePopup={handleClosePopup}
/>
</div>
);
})}
Handle Update Code
const [menuName, setMenuName] = useState("");
const [menuPrice, setMenuPrice] = useState(0);
const handleUpdate = (e, mid) => {
e.preventDefault();
const url = `http://localhost:5000/restaurant/menu/${mid}`;
const data = { menuName, menuPrice };
console.log(mid);
axios
.patch(url, data)
.then((res) => {
handleClosePopup();
setRestaurant(res.data);
})
.catch((err) => console.log("Some error occured ", err));
};
Этот код отображает элементы из меню
import React from "react";
import { makeStyles } from "@mui/styles";
import { Box, Grid, Button, Divider, Modal } from "@mui/material";
import { FormGroup } from "react-bootstrap";
import { useState } from "react";
const style = {
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
width: 925,
bgcolor: "background.paper",
border: "1px solid #141414",
borderRadius: "8px",
boxShadow: 24,
p: 4,
justifyContent: "space-between",
};
const useStyles = makeStyles((theme) => ({
avatar: {
margin: "0 8px",
},
input: {
padding: "10px",
lineHeight: "normal",
textAlign: "center",
"amp;amp;:placeholder": { color: "#f00" },
},
submit: {},
}));
export default function EditDish({
dish,
btnName,
handleFunction,
updateFunction,
setMenuName,
setMenuPrice,
openPopup,
handleOpenPopup,
handleClosePopup,
}) {
const classes = useStyles();
const [menuID, setMenuID] = useState(dish._id);
return (
<>
<div className="card mx-2" style={{ width: "20rem" }}>
<div className="card-title">{dish.menuName}</div>
<p className="card-text">
Rs.{dish.menuPrice} <br />
<button
onClick={handleFunction}
className="btn btn-outline-success float-end m-2"
>
{btnName}
</button>
<button
onClick={() => {
// setMenuID(dish._id);
handleOpenPopup();
}}
className="btn btn-outline-success float-top-end m-2"
>
Update
</button>
</p>
</div>
<Modal
open={openPopup}
onClose={handleClosePopup}
aria-labelledby="login-modal-title"
aria-describedby="login-modal-description"
>
<Box sx={style}>
<div className="paperLogin">
<h6>Edit Restaurant Details</h6>
<div
className="container"
style={{ overflow: "scroll", maxHeight: "300px" }}
>
{/* Make axios request instead of form action */}
{/* Create Function to do this */}
<form
className={classes.form}
// onSubmit={(e) => updateFunction(e, menuID)}
onSubmit={updateFunction}
>
<Grid container spacing={1}>
<Grid item xs={12}>
<FormGroup>
<input
type="text"
className="form-control"
name="menuName"
placeholder="Menu Name"
onChange={(e) => setMenuName(e.target.value)}
/>
</FormGroup>
</Grid>
<Grid item xs={12}>
<FormGroup>
<input
type="number"
className="form-control"
name="menuPrice"
placeholder="Menu Price"
onChange={(e) => setMenuPrice(e.target.value)}
/>
</FormGroup>
</Grid>
<Grid item xs={12}>
<Button
type="submit"
fullWidth
// onClick={handleSubmit}
variant="contained"
color="primary"
className={classes.submit}
>
Submit
</Button>
</Grid>
<Grid item xs={12}>
<Divider spacing={1}></Divider>
</Grid>
</Grid>
</form>
</div>
</div>
</Box>
</Modal>
</>
);
}
Проблема в том, что console.log(mid);
всегда отображается идентификатор последнего элемента в списке(массив меню). Я отладил компонент с помощью инструментов разработчика React, и идентификаторы переданы правильно.
Есть какие-нибудь решения?
Комментарии:
1. Не могли бы вы, пожалуйста, обновить метод setRestaurant?