Поле карты Mongoose не обновляется с помощью вызова doc.save () - PullRequest
0 голосов
/ 14 января 2019

Я пытаюсь обновить обновление модели Cart в моем mongoDB с помощью Mongoose. В моей модели корзины у меня есть 2 типа схемы карты, которые называются itemsList и itemsPrices. Проблема, которую я получаю, очень странная в том, что, когда я пытаюсь «оформить» свою корзину, другие поля моей модели сохраняются и обновляются, такие как промежуточный итог, статус и т. Д., Но изменения, которые я делаю в моих двух полях карты, не сохраняться в БД.

То, что я уже сделал, - это проверка того, что элемент изменяется, и карта изменяется, прежде чем я вызову функцию сохранения для объекта корзины, проверяя, действительно ли обновляются другие поля. Это странно, потому что, когда я пытался добавить товар в корзину, т.е. добавить значение в 2 поля карты, они обновлены и сохранены в БД. Тем не менее, когда я пытаюсь удалить их, они не продолжают удаление.

My CartModel

let CartSchema = new mongoose.Schema({
  itemsList: {
    type: Map,
    of: Number
  },
  itemsPrices: {
    type: Map,
    of: Number
  },
  subtotal: {
    type: Number,
    default: 0
  },
  status: {
    type: String,
    enum: ['open', 'partially-completed', 'completed'],
    default: 'open'
  },
  fulfilled: {
    type: Date
  }
})

Мой маршрут оформления заказа в экспрессе

//Checks out a cart
router.put('/api/cart/:id/checkout', (req, res) => {
  CartModel.findById(req.params.id)
    .then(cart => {
      console.log(cart)
      let checkedOutCart = checkoutCart(cart)
      console.log(checkedOutCart)
      cart = checkedOutCart //also tried cart.set(checkedOutCart)
      cart.save(function(err, doc) {
        if (err) {
          return res.status(400).send(err)
        }
        res.json(doc)
      })
    })
    .catch(err => {
      console.log(err)
      return res.status(400).json(err)
    })
})

Функция My checkoutCart (корзина)

function checkoutCart(cart) {
  for (const [itemId, quantity] of cart.itemsList) {
    console.log(`Trying to purchase item: ${itemId}, Quantity: ${quantity}`)
    let leftInCart = purchaseItem(itemId, quantity)
    //Not enough inventory to purchase all items
    if (leftInCart > 0) {
      //Update the quantity of the item with how much is left
      cart.itemsList.set(itemId, leftInCart)
    } else {
      //Remove the item from the prices and quantity lists
      cart.itemsList.delete(itemId)
      cart.itemsPrices.delete(itemId)
    }
  }
  //Update the carts subtotal (in the case there are still items left) - using 888 to just check that this field actually got updated
  cart.subtotal = 888
  //Update the carts status
  if (cart.itemsList.size > 0) {
    cart.status = 'partially-completed'
  } else cart.status = 'completed'
  return cart
}

Это моя другая функция addToCart, которая успешно обновляет карту

//Add item to cart
router.put('/api/cart/:id', (req, res) => {
  if (req.body) {
    CartModel.findById(req.params.id)
      .then(cart => {
        cart = addToCart(cart, req.body)
        cart.save(function(err, doc) {
          if (err) {
            return res.status(400).send(err)
          }
          res.json(doc)
        })
      })
      .catch(err => {
        console.error(err)
        return res.status(400).send(err)
      })
  } else {
    return res.status(404).send('Body is missing.')
  }
})
//Updates the cart with a new item
function addToCart(cart, body) {
  let itemId = body.itemId
  let quantityToAdd = body.quantity || 1
  let price = body.price
  //If the cart already has the item, increment its quantity
  if (cart.itemsList.has(itemId)) {
    let currentQuantity = cart.itemsList.get(itemId)
    cart.itemsList.set(
      itemId,
      currentQuantity + quantityToAdd // Add item to the items_list of the cart and its associated price
    )
  } else {
    // Add the item to the cart
    cart.itemsList.set(itemId, quantityToAdd)
    cart.itemsPrices.set(itemId, price)
  }
  cart.subtotal = cart.subtotal + quantityToAdd * price
  return cart
}

Теперь, как вы можете видеть, обе функции в основном работают одинаково. Я в основном делаю некоторые изменения в объекте корзины, возвращаемом моделью, затем, когда я выполнил свою логику для полей, я пытаюсь вызвать save, и каждое поле, кроме 2 карт, обновляется при вызове checkout, но это прекрасно работает для вызов addToCart. Вот объекты до и после логики (журналы консоли) для вызова извлечения.

Console.log (корзина) корзины, полученная из БД

{ subtotal: 2750,
  status: 'open',
  _id: 5c3bd0e03858b8f48d2cd3af,
  itemsList:
   Map {
     '5c3bc2e2141303f3207cb646' => 1,
     '5c3bc306141303f3207cb647' => 1 },
  itemsPrices:
   Map {
     '5c3bc2e2141303f3207cb646' => 1000,
     '5c3bc306141303f3207cb647' => 1750 },
  __v: 0 }

Console.log (checkOutCart) корзины с обновленными полями для сохранения

{ subtotal: 0,
  status: 'completed',
  _id: 5c3bd0e03858b8f48d2cd3af,
  itemsList: Map {},
  itemsPrices: Map {},
  __v: 0 }

Теперь также интересна моя функция сохранения res.json(doc) на самом деле возвращает второй контент selectedOutCart обратно, но фактически не сохраняет его в БД. Когда я вызываю БД для этой корзины, я вижу обновленный промежуточный итог, статус, но карты все еще остаются такими же, с предметами и ценами, которые все еще в них (должны быть пустыми).

Я не уверен, что я делаю неправильно.

UPDATE: Поэтому я заметил, что если я изменил значения itemsList на 0, вместо того, чтобы удалить его с карты, он обновится. Однако, кажется, я не могу обновить его с пустой картой, почему?

1 Ответ

0 голосов
/ 14 января 2019

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

A MongooseMap является подклассом встроенного класса Map. В этих документах мы будем использовать термины «карта» и MongooseMap взаимозаменяемо. В Mongoose карты - это способ создания вложенного документа с произвольными ключами.

Примечание. В Mongoose Maps ключи должны быть строками для хранения документа в MongoDB .

Итак, в схеме

let CartSchema = new mongoose.Schema({
  itemsList: {
    type: Map,
    of: String //should be string
  },
  itemsPrices: {
    type: Map,
    of: String //should be string
  },
  subtotal: {
    type: Number,
    default: 0
  },
  status: {
    type: String,
    enum: ['open', 'partially-completed', 'completed'],
    default: 'open'
  },
  fulfilled: {
    type: Date
  }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...