Как обновить объект внутри массива документов Mongo (по определенному индексу) - PullRequest
0 голосов
/ 31 мая 2019

Я хочу позволить пользователю отмечать, приобрели ли он продуктовый продукт, и обновлять базу данных.

Если говорить более конкретно, когда пользователь устанавливает флажок, я хочу переключить логическое значение.свойство acquired на объекте ингредиента.Ингредиенты хранятся в массиве в документе GroceryList:

Вот схема для списка покупок

const GroceryListSchema = mongoose.Schema({
  createdAt         : { type: Date, default: Date.now },
  updatedAt         : { type: Date },
  ingredients       : { type: Array },
  recipes           : { type: Array },
  user              : { type: mongoose.Schema.Types.ObjectId, ref: 'UserSchema', required: true },
}

Ингредиент выглядит так:

{ quantity: '3',
  unit: null,
  ingredient: 'zucchinis, chopped',
  minQty: '3',
  maxQty: '3',
  acquired: false }

Я просмотрел много похожих вопросов, документацию Mongoose и документацию MongoDB, и я попробовал множество различных версий, но я в тупике.

Внешний интерфейс:

function toggleIngredient(elmt, groceryListId, ingrIdx) {
  $.post('/cart/grocery-list/toggleIngredient', {
    groceryListId,
    ingrIdx,
    newValue: elmt.checked, // if checkbox was checked before toggling it
  })
    .then((res) => {
      console.log(res);
    })
    .catch((err) => {
      console.log(err);
    });
}

Backend:

  app.post('/cart/grocery-list/toggleIngredient', (req, res, next) => {
    const { groceryListId, ingrIdx, newValue } = req.body;

    GroceryListSchema.findById(groceryListId, (err, groceryList) => {
      if (err) return next(err);

      // if was unchecked, change to checked & vice-versa
      groceryList.ingredients[ingrIdx].acquired = newValue;

      // save updated grocery list
      groceryList.save().then((updatedList) => {
        console.log(updatedList.ingredients);
      }).catch(error => next(error));
    });
  });

РЕЗУЛЬТАТЫ / ПРОБЛЕМА: Когда я запускаю приведенный выше код, я успешно вижу, как свойство acquired одного ингредиента переключается с false -> true в обратном вызове

console.log(updatedList.ingredients);

Однако, когда я в следующий раз получу список покупок, тот же самый ингредиент acquired = false.Это наводит меня на мысль, что документ GroceryList на самом деле не обновляется в базе данных.Как мне это исправить?

1 Ответ

1 голос
/ 31 мая 2019

mongoose не может отслеживать изменения внутри массива, если вы изменяете элемент массива напрямую, используя его индекс

попробуйте добавить эту строку перед сохранением

groceryList.markModified(`ingredients.${ingrIdx}.acquired`);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...