在Mongo后端使用findOne()检索后,在对象数组上运行forEach()

时间:2018-10-29 20:02:46

标签: arrays mongodb mongoose

我正在使用findOne()来检索这样的文档:

  let staffToUpdate = await Staff.findOne({
    _id: request.parameters.id
  }).exec();

  let historyArray = await crewToUpdate.history;

  console.log("historyArray: ", await historyArray);

  console.log(Array.isArray(historyArray)); // returns true

数据如下:

history: [
  {
   status: "active",
   startDate: <Date>,
   endDate: <Date>, 
   completed: false
  },
  {
   status: "training",
   startDate: <Date>,
   endDate: <Date>, 
   completed: true
  }
]

执行上述操作时,我得到了打印出的对象数组,并在检查中返回“ true”以查看“ historyArray”是否确实是数组。

现在我有了这个数组,我想对在其中找到的对象进行转换,就像这样:

  let updatedHistoryArray = historyArray.then(
    updatedHistoryArray.forEach(history => {
      history.completed = true;
      history.endDate = new Date();
    })
  );

但是,这是不起作用的部分。当我尝试此操作时,出现此错误:

  

原因:ReferenceError:historyArray未定义

我在这里想念什么?

更新:在以下评论者的建议下,我尝试了以下方法:

  let staffToUpdate = await Staff.findOne({
    _id: request.parameters.id
  }).exec();

  let staffObject = staffToUpdate.toObject();

  let historyArray = await staffObject.history;

  console.log(await historyArray); // prints the array

  console.log(Array.isArray(historyArray)); // returns true

  historyArray.forEach(history => { // this is where the error occurs
    history.completed = true;
    history.endDate = new Date();
  });

在这最后的代码块中,我得到此错误:

  

原因:ReferenceError:historyArray未定义

1 个答案:

答案 0 :(得分:1)

historyArray不是Promise,您不能在其上运行then。 该代码何时运行

let staffToUpdate = await Staff.findOne({
    _id: request.parameters.id
}).exec();

它等待直到执行查询,然后分配实际结果(猫鼬文档)而非承诺,并将其分配给staffToUpdate。您需要在猫鼬文档上运行toObject(),以获取没有包装器的纯对象:

const unwrappedStaffToUpdate = staffToUpdate.toObject();

此后,您无需在await上使用crewToUpdate.history,因为它不是Promise,而是同步的。这就是为什么您不能在then上运行historyArray的原因,因为它是普通数组而不是Promise。

尝试以下代码:

unwrappedStaffToUpdate.historyArray.forEach(history => {
      history.completed = true;
      history.endDate = new Date();
});

或者,如果您不想更改数组,请使用map而不是forEach

const updatedHistoryArray = unwrappedStaffToUpdate.historyArray.map(history => ({
          ...history 
          completed: true;
          endDate: new Date()
      })
);