Node.js – [CRUD] обновление

Вопрос или проблема

Я создал menu-edit.pug, чтобы показать свою форму редактирования, надеюсь, что пользователи нажмут на ссылку меню, перейдут на эту страницу редактирования и внесут некоторые изменения. При отправке формы обновленное значение будет сохранено и произойдет перенаправление на страницу меню.

Мой код: страница редактирования готова, но что-то не так с моими действиями по редактированию/отправке. Когда я отправляю обновленные данные в браузере, создается новая ссылка вместо перезаписи существующей.

Страница menu-edit

block layout-content
    div.content
        h1.page-title Редактировать ссылку меню
        //- /admin/menu/edit/submit будет местом, куда отправляются данные формы
        form(method="post", action="/admin/menu/edit/submit")
            input(type="hidden", name="linkId", value=editLink._id)
            div 
                label(for="wgt") Вес: 
                input(type="number", id="wgt", name="weight", value=editLink.weight)
            div 
                label(for="href") URI: 
                input(type="text", id="href", name="path", value=editLink.path)
            div 
                label(for="link-name") Текст ссылки: 
                input(type="text", id="link-name", name="name", value=editLink.name)
            button(type="submit") Обновить ссылку

Мой index.js выглядит следующим образом:

app.get("/admin/menu/edit", async (request, response) => {
  if (request.query.linkId) {
    let linkToEdit = await getSingleLink(request.query.linkId);
    let links = await getLinks();
    response.render("menu-edit", { title: "Редактировать ссылку меню", menu: links, editLink: linkToEdit });
  }
  else {
    response.redirect("/admin/menu");
  }
});

app.post("/admin/menu/edit/submit", async (request, response) => {
  let id = request.query.linkId; 
  let idFilter = { _id: new ObjectId(id)};
  let link = {
      weight: parseInt(request.body.weight),
      path: request.body.path,
      name: request.body.name
  };
  await editLink(idFilter, link);
  response.redirect("/admin/menu");
})

async function getSingleLink(id) {
  db = await connection();
  const editId = { _id: new ObjectId(id) };
  const result = await db.collection("menuLinks").findOne(editId);
  return result;
}

async function editLink(filter, link) {
  db = await connection();
  const options = { upsert: true };
  // Укажите обновление для установки значения для поля link
  let updateLink = {
    $set: {
    weight: link.weight,
    path: link.path,
    name: link.name
    }
};
  let result = await db.collection("menuLinks").updateOne(filter, updateLink, options);
  // Вывод количества соответствующих и измененных документов
  // https://www.mongodb.com/docs/drivers/node/current/usage-examples/updateOne/#std-label-node-usage-updateone
  console.log(
    `${result.matchedCount} документ(ов) соответствует фильтру, обновлено ${result.modifiedCount} документ(ов)`,
  );
}

Ответ или решение

Ваша проблема заключается в неправильном использовании идентификатора ссылки при отправке данных формы на сервер. В функции обработки POST-запроса для обновления линков вы извлекаете linkId из request.query, однако форма отправляет linkId как скрытое поле, которое доступно через request.body. Это объясняет, почему при отправке формы создаётся новая запись вместо обновления существующей.

Вот так можно изменить ваш код для правильной обработки обновления:

1. Изменение маршрута для обработки обновления

Вместо извлечения linkId из запроса, вам нужно получить его из request.body.

app.post("/admin/menu/edit/submit", async (request, response) => {
  let id = request.body.linkId;  // Изменено на получение из request.body
  let idFilter = { _id: new ObjectId(id) };
  let link = {
    weight: parseInt(request.body.weight),
    path: request.body.path,
    name: request.body.name
  };

  // Обновление ссылки с использованием правильного фильтра
  await editLink(idFilter, link);
  response.redirect("/admin/menu");
});

Вы уже используете updateOne с правильным фильтром и обновлением, так что остальная часть вашей функции сохранения изменений выглядит хорошо:

async function editLink(filter, link) {
  db = await connection();
  const options = { upsert: false }; // Убедитесь, что upsert отключен
  let updateLink = {
    $set: {
      weight: link.weight,
      path: link.path,
      name: link.name
    }
  };
  let result = await db.collection("menuLinks").updateOne(filter, updateLink, options);
  console.log(
    `${result.matchedCount} документ(ов) соответствует фильтру, обновлено ${result.modifiedCount} документ(ов)`,
  );
}

3. Общее замечание

Убедитесь, что у вас корректно настроен middleware для обработки express и что вы используете body-parser для получения данных из тела запроса. Например:

const express = require('express');
const bodyParser = require('body-parser');
const app = express();

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

Заключение

С внесёнными изменениями ваш код должен корректно обрабатывать обновления, и данные будут изменяться вместо создания новых записей. Не забудьте проверить консоль на вывод ошибок, которые могут возникнуть, чтобы убедиться, что все операции выполняются успешно.

Оцените материал
Добавить комментарий

Капча загружается...