Express.js和MongoDB:对嵌套对象的PUT请求

时间:2019-07-18 15:50:49

标签: javascript mongodb express mongoose mongoose-schema

我正在尝试发出PUT请求以更新单个项目的数据,每个项目包含一个MongoDB文档。它适用于所有键,但socialLinks键除外,它由对象twitterfacebookinstagram组成。

我可以使用以下代码将数据发布到这些对象中:

router.post(
  '/',
  [
    auth,
    [
      check('itemName', 'Name is required')
        .not()
        .isEmpty(),
      check('companyName', 'Company name is required')
        .not()
        .isEmpty(),
      check('thumbnailFileName', 'Thumbnail is required').isURL(),
      check('tagline', 'Tagline is required')
        .not()
        .isEmpty(),
      check('description', 'Description is required')
        .not()
        .isEmpty(),
      check('topics', 'At least one topic is required')
        .not()
        .isEmpty(),
      check('website', 'At least one topic is required').isURL(),
      check('availability', 'Availability is required')
        .not()
        .isEmpty(),
      check('socialLinks.twitter', 'Please enter a valid URL').isURL(),
      check('socialLinks.facebook', 'Please enter a valid URL').isURL(),
      check('socialLinks.instagram', 'Please enter a valid URL').isURL()
    ]
  ],
  async (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({ errors: errors.array() });
    }

    const {
      itemName,
      companyName,
      thumbnailFileName,
      tagline,
      description,
      topics,
      website,
      availability,
      makers,
      socialLinks: { twitter, facebook, instagram }
    } = req.body;

    try {
      const newItem = new Item({
        user: req.user.id,
        itemName,
        companyName,
        thumbnailFileName,
        tagline,
        description,
        topics,
        website,
        availability,
        makers,
        socialLinks: { twitter, facebook, instagram }
      });

      const item = await newItem.save();

      res.json(item);
    } catch (err) {
      console.error(err.message);
      res.status(500).send('Server Error');
    }
  }
);

但是我在使用PUT路由更新socialLinks数据时遇到了一些麻烦:

router.put('/:id', auth, async (req, res) => {
  const {
    itemName,
    companyName,
    thumbnailFileName,
    tagline,
    description,
    topics,
    website,
    availability,
    makers,
    socialLinks
    // socialLinks: { twitter, facebook, instagram }
  } = req.body;

  // Build item object
  const itemFields = {};
  if (itemName) itemFields.itemName = itemName;
  if (companyName) itemFields.companyName = companyName;
  if (thumbnailFileName) itemFields.thumbnailFileName = thumbnailFileName;
  if (tagline) itemFields.tagline = tagline;
  if (description) itemFields.description = description;
  if (topics) itemFields.topics = topics;
  if (website) itemFields.website = website;
  if (availability) itemFields.availability = availability;
  if (makers) itemFields.makers = makers;
  if (socialLinks) itemFields.socialLinks = socialLinks;
  // if ({socialLinks: { twitter, facebook, instagram }}) itemFields.socialLinks[{socialLinks: { twitter, facebook, instagram }}] = {socialLinks: { twitter, facebook, instagram }};

  try {
    let item = await Item.findById(req.params.id);

    if (!item) return res.status(404).json({ msg: 'Item not found' });

    // Make sure user owns item
    if (item.user.toString() !== req.user.id) {
      return res.status(401).json({ msg: 'Not authorized' });
    }

    item = await Item.findByIdAndUpdate(
      req.params.id,
      { $set: itemFields },
      { new: true }
    );

    res.json(item);
  } catch (err) {
    console.error(err.message);
    res.status(500).send('Server Error');
  }
});

我尝试了各种组合以使其起作用。在PUT路线中,如果仅分解socialLinks,而在itemFelds中仅包含if (socialLinks) itemFields.socialLinks = socialLinks;,则可以同时更改一个或多个socialLinks,但如果不这样做,不包含所有socialLinks,然后删除我未包含在我的PUT请求中的那些内容。

猫鼬模式:

const mongoose = require('mongoose');

const ItemSchema = mongoose.Schema({
  user: {
    type: mongoose.Schema.Types.ObjectId,
    refer: 'users'
  },
  itemName: {
    type: String,
    required: true
  },
  companyName: {
    type: String,
    required: true
  },
  thumbnailFileName: {
    type: String,
    required: true
  },
  tagline: {
    type: String,
    required: true
  },
  description: {
    type: String,
    required: true
  },
  topics: [
    {
      type: String,
      required: true
    }
  ],
  website: {
    type: String
  },
  availability: {
    type: String,
    required: true
  },
  makers: [
    {
      type: String
    }
  ],
  socialLinks: {
    twitter: {
      type: String
    },
    facebook: {
      type: String
    },
    instagram: {
      type: String
    }
  },
  date: {
    type: Date,
    default: Date.now
  }
});

module.exports = mongoose.model('item', ItemSchema);

0 个答案:

没有答案