无法在地图回调中返回修改后的对象。我做错了什么?

时间:2017-03-02 20:17:25

标签: javascript node.js mongodb mongoose array.prototype.map

这是在node.js / express / mongoose上运行的路由... 'Department'是Mongoose.js模型

  1. 第一个'Department.find()'调用返回一个对象数组,其中每个对象如下所示:

    { _id: 58a4b5991a1214ff1f2c5406, name: 'Information Technology', manager: 58a60a581a1214ff1f2c5415, parent: 58a4b23c1a1214ff1f2c5405, primaryLoc: [ 58a5db4c1a1214ff1f2c5414 ] }

  2. 我想返回具有父级deptartment名称的JSON而不仅仅是id。

  3. 我.map()在返回的'departements'数组上。在'Parent'Id上执行Department.FindOne()。这成功找到父级的名称。然后我尝试将'parentName'键添加到对象。
  4. 这似乎可以console.log('ParentName' + thisObj.parentName)
  5. 起作用
  6. 无论我尝试什么,但返回对象不包含添加的密钥。
  7. 这是我的代码:提前致谢!

    router.get('/departments', function(req, res) {
    
      Department.find({}, function(err, departments) {
        if (err) throw err
    
        //Find the names of the parent departments
        let newDepts = departments.map(function(dept) {
    
          let thisObj = dept
          Department.findOne({ _id : dept.parent })
    
          .then(function(foundDept){
              if (foundDept) {
                thisObj['parentName'] = foundDept.name
                console.log(`thisObj has the key now?: parentName = ${thisObj.parentName}`) //This works
                console.log(`thisObj: ${thisObj}` ) //Nope. No parentName key?? 
                return thisObj
              } else {
                thisObj['parentName'] = "TopLevelDeptartment"
                return thisObj
              }
    
          })
    
        })
    
        res.json(newDepts)
    
      })
    
    })
    

    在这里有你的帮助是我的新代码......不幸的是res.body有11个空条目。 (现在dbase中只有11个depts)...如果我在find()之后将thisObj记录到控制台,那么它是一个完全填充的对象,所以我知道find函数正在工作。我也可以将parentName记录到控制台,所以我知道findOne()正在运行。还缺少什么?

    router.get('/departments', function(req, res) {
    
      Department.find({}, function(err, departments) {
        if (err) throw err
    
    
        //Find the names of the parent departments
        Promise.map(departments, function(dept) {
          let thisObj = dept
          Department.findOne({ _id : dept.parent }, function(foundDept){
              if (foundDept) {
                thisObj['parentName'] = foundDept.name
              } else {
                thisObj['parentName'] = "No Parent"
              }
          })
    
        }).then(function(depts){
          console.log(`depts.length: ${depts.length}`)
          res.json(depts)
        })
    
    
      })
    
    }) 
    

1 个答案:

答案 0 :(得分:2)

您的代码中有异步操作。您映射部门,但在对象映射后运行db调用。所以你返回原来的部门,一段时间后你的Moongose findOne函数返回结果并更新已经处理过的对象。您可以看到它已更新,但它不会更改原始对象。

Bluebird Promises解决方案示例:

var Promise = require('Bluebird')

Promise.map(departments, function(dept) {
      return Department.findOne({ _id : dept.parent }, function(foundDept){
          if (foundDept) {
            dept['parentName'] = foundDept.name
          } else {
            dept['parentName'] = "No Parent"
          }
          return dept
      })
    }).then(function(depts){
      res.json(depts)
    })

Bluebird会负责等待你的findOne结果,最后会返回转换后的relratments。