Обновите значения массива в react axios mongodb

#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?