【问题标题】:How do I update an object from an outer function?如何从外部函数更新对象?
【发布时间】:2017-09-07 20:11:14
【问题描述】:

在这个猫鼬功能上苦苦挣扎。我正在尝试在另一个嵌入对象中添加一个嵌入对象,但它将新的出价对象添加到错误的位置 - 我为迭代器创建的新列表变量。 我的 for 循环试图找到要更新的确切列表,所以我认为分配它们的操作会弄乱它们。例如,如果列表是 users[2].listings[10].bids ,我如何获取该对象以便更新它?

 function create(req, res) {
   db.Listing.findById(req.params.listingId, function(err, foundListing) {
    // console.log(foundListing._id );
    if (err) {
      console.log('Error', err);
    }
     // res.json(foundListing);
     // get array of all users
    db.User.find({}, function(err, users) {
      // for loop iterates through all users' listings
      for (let i = 0; i < users.length; i++) {
        let listings = users[i].listings
        // for loop iterates through all listings ids
        for (let j = 0; j < listings.length; j++) {
          // finds match
          // comparing _id with _id returning false. Not sure why, will return later
          if (listings[j].topic === foundListing.topic && listings[j].created === foundListing.created) {
            console.log("Found match: " + foundListing.topic);
            // get current user id to add to bid object
            db.User.findById(req.user, function(err, user) {
              if (err) {
                console.log(err);
              }
              var newBid = new db.Bid(req.body); // add data validation later
              newBid.uid = user._id
              // pushes new bid object into embedded listing
              listings[j].bids.push(newBid);
              listings[j].save(function(err, savedBid) {
               console.log('newBid created: ', newBid);
               console.log(listings[j]);
               res.json(newBid);
              });
            });
          }
        }
      }
    })
    if (err) {
      console.log(err);
    }
  });
};

编辑 - 到目前为止,但现在我的数组似乎没有保存。

function create(req, res) {
  db.Listing.findById(req.params.listingId, function(err, foundListing) {
    if (err) {
      console.log('Error:', err);
    }
    db.User.findOne({ 'listings._id': req.params.listingId }, function(err, foundUser) {
      // console.log(foundUser.listings);
      if (err) {
        console.log('Error: ', err);
      }
      for (let i = 0; i < foundUser.listings.length; i++) {
        // console.log(foundUser.listings[i]._id);
        if (foundUser.listings[i]._id == req.params.listingId) {
          console.log( 'found it! - ' + foundUser.listings[i].topic);
          var newBid = new db.Bid(req.body);
          // console.log(newBid)
          foundUser.listings[i].bids.push(newBid);
          console.log(foundUser.listings[i].bids)
          foundUser.listings[i].save(function(err, savedListing) {
            // console.log(foundUser.listings[i])
            if (err) {
              console.log('Error: ', err);
              return;
            }
              console.log('newBid created: ', newBid);
              console.log('savedListing', savedListing);
              res.json(newBid);
          })
        }
      }
    })
  });
};

【问题讨论】:

  • 你到底想在这里做什么?您希望将 newBid 放置在哪里?尝试提供更多详细信息
  • 我有一个嵌入列表的用户集合。所以 1 个用户可以有很多列表。然后每个列表可以有许多嵌入列表中的投标(响应)。由于它的设置方式,当一个人响应出价时,该函数将搜索该列表的位置(嵌入在用户中),一旦找到该列表,该出价对象将被推送到该列表对象中,这是嵌入在该用户对象中。我的问题是它没有推入原始列表数组,而是被推入我为迭代器创建的列表变量数组中
  • 如果您的变量名发生冲突,则只需重命名其中一个。 let userListings = users[i].listings
  • 你有一个叫做req.user的东西,你用它来通过id查找用户,这看起来也有点有趣。但你只是发出获取用户的请求,这样你就可以得到用户id.. 你不是已经在req.userreq.user.id 中拥有用户ID 了吗?
  • 好吧,我的 for 循环正试图找到要更新的确切清单,所以我认为分配它们的操作把它们弄乱了。例如,如果列表是 users[2].listings[10].bids ,我如何获取该对象以便更新它?

标签: javascript node.js mongoose scope


【解决方案1】:

您拥有的代码很难掌握。我认为您可能使用了错误的工具来解决问题。 MongoDb 和 Mongoose 似乎具有相当高级的查询功能,因此您可以指定您感兴趣的确切用户、列表等。

我认为值得您花时间查看Mongoose queriesMongoDb queries 的文档。在db.User.findOne({ 'listings.id': req.params.listingId } 中用于listings.id.described here

我无法真正测试此代码是否可以编译或是否可以工作,因为我对您的数据库模型等了解不够,但是应该可以进行以下操作:

 function create(req, res) {
   db.Listing.findById(req.params.listingId, function(err, foundListing) {
    // use the power of mongo db and mongoose.
    // you can specify more exactly what you're looking for
    // in this case we're interested in ONE user that
    // has a listing with a specific id  
    // (if you still problems with comparing identical IDs, then that's a serious issue..
    //  maybe try logging req.params.listingId and check if it really exists
    // in your database.)
    db.User.findOne({ 'listings.id': req.params.listingId }, function(err, foundUser) {
      var newBid = new db.Bid(req.body); // add data validation later
      newBid.uid = foundUser._id

      // Old code: foundListing.bids.push(newBid) 

      // Change according to first question/answer at  http://mongoosejs.com/docs/faq.html
      // which was linked in the thread you linked to in comment.
      // The essence is that Mongoose doesn't get
      // notified about changes to arrays by default
      // To get around this you can update using "set"
      // but then you need both a value and an index:
      var oldBidsLength = foundListing.bids.length;
      foundListing.bids.set(oldBidsLength, newBid);     

      foundListing.save(function(err, savedBid) {
        // savedBid  =  saved LISTING? 
        console.log('newBid created: ', newBid);
        console.log('savedBid', savedBid);
        res.json(savedBid);
        }
      }
    })
  });
};

此代码示例可能会出现问题,例如 db.User.findOne({ 'listings.id': req.params.listingId } 是否应该与 listings._id 一起使用。我对你的模型了解不够。

【讨论】:

  • 感谢您的回复,并将尝试一下!我环顾四周寻找示例,this walk-through 演示了与我原来的帖子类似的内容。因此,我将出价嵌入在用户中嵌入的列表中,并且我正在尝试根据我正在响应的列表添加新的出价(使用 AngularJS,因此 listingId 有效)
  • 好的,是的,我可能对 MongoDb 语法和 Mongoose 语法之间的重叠有误。但似乎它可能足以让我的建议发挥作用,至少根据这个:stackoverflow.com/questions/35214194/…
  • 让我知道它是怎么回事,如果你需要别的东西。 (不过现在是睡觉时间,所以我暂时不会回答。)
  • 编辑了我的回复以包括我上面的进度。它控制台一直记录到savedListing,但此时savedListing 是未定义的。我认为我没有正确保存数组,在阅读 [this] (github.com/Automattic/mongoose/issues/1204) 之后,我不确定如何将它应用到我的代码中。
  • 不错的发现!很难准确猜测库/框架的智能程度。有些事情只是“自动神奇地”工作,而其他事情则不然。无论如何,在您的链接中,我看到一个解决方案与错误的架构有关,但我不知道如何将其应用于您的代码。但另一个人提出了一个更简单的解决方案,即“手动”告诉 Mongoose 数组已更新。我已经编辑了我的答案以反映新知识。希望这可以解决问题。
猜你喜欢
  • 1970-01-01
  • 2020-04-06
  • 2021-12-22
  • 2020-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-02
相关资源
最近更新 更多