[英]findOne filtering by objectId always returns undefined
開發 node.js 應用程序。 出於某種原因,這個 findOne 調用總是返回未定義,即使我已經驗證 req.params.id 是有效的,它應該返回數據......
let event = await Event.findOne({ venue: ObjectId(req.params.id) });
我也試過了....
let event = await Event.findOne({ venue: req.params.id });
這是我的 Event 模型定義的一部分....
const EventSchema = new mongoose.Schema({
eventDate: {
type: Date
},
venue: {
type: mongoose.Schema.ObjectId,
ref: 'Venue'
},
在郵遞員中,我正在針對/venues/5e0401c4a246333ca4ced332 url 執行DELETE http 動詞以供您參考。
基本上我想在事件表中搜索場地 ID。 在我決定刪除它之前,我正在查看該場地是否正在被某個活動使用。
這是整個方法...
// @desc Delete venue
// @route DELETE /api/v1/venues/:id
// @access Private
exports.deleteVenue = asyncHandler(async (req, res, next) => {
let venue = await Venue.findById(req.params.id);
if (!venue) {
return next(
new ErrorResponse(`No venue with the id of ${req.params.id}`, 404)
);
}
if (req.user.role !== 'manager' && req.user.role !== 'admin') {
return next(new ErrorResponse(`Not authorized to delete venue`, 401));
}
// the following line always returns undefined even though the venue
// exists in the events table.... then it jumps to the end of the method
let event = await Event.findOne({ venue: ObjectId(req.params.id) });
if (event) {
return next(
new ErrorResponse(
`You cannot delete a venue because events are tied to it.`,
404
)
);
}
await Venue.remove();
res.status(200).json({
success: true,
data: {}
});
});
使用指南針,查看事件集合,我肯定會看到使用我提交的 id 的記錄......
_id:5e045b6e0c38f2502440ecb7
attendees:Array
eventDate:2020-01-01T05:00:00.000+00:00
venue:5e0401c4a246333ca4ced332
status:"planning"
我做了...
console.log(`id is ${req.params.id}`);
let event = await Event.findOne({ venue: req.params.id });
結果顯示我傳遞了正確的 id....(控制台輸出)
id is 5e0401c4a246333ca4ced332
ReferenceError: Event is not defined
at C:\Projects\abc\controllers\venues.js:90:15
任何見解將不勝感激。 謝謝!
您似乎沒有導入事件模型。 您需要添加:
const Event = require("../models/event"); //you need to change the path
之后你需要找到這樣的事件: Event.findOne({ venue: req.params.id })
。
另外我有幾點建議:
1-) 在開始時檢查角色授權更有意義。
2-) 首先檢查給定的 Venue 是否有任何事件,如果沒有事件,則使用findByIdAndDelete
方法。 這樣我們就可以減少數據庫訪問的次數,因為我們消除了Venue.findById
3-) 如果場地有活動,使用 404 狀態代碼似乎不正確。 我認為 400 - Bad request 更合適。
4-) mongoose 會轉換 _id 的,所以不需要使用 ObjectId。
exports.deleteVenue = asyncHandler(async (req, res, next) => {
if (req.user.role !== "manager" && req.user.role !== "admin") {
return next(new ErrorResponse(`Not authorized to delete venue`, 401));
}
let event = await Event.findOne({ venue: req.params.id });
if (event) {
return next(new ErrorResponse(`You cannot delete a venue because events are tied to it.`,400));
}
let venue = await Venue.findByIdAndDelete(req.params.id);
console.log(venue);
if (!venue) {
return next(new ErrorResponse(`No venue with the id of ${req.params.id}`, 404));
}
res.status(200).json({
success: true,
data: {}
});
});
測試:
假設我們有以下兩個 Venue 文件。
{
"_id" : ObjectId("5e0471e3394d1e2b348b94aa"),
"name" : "Venue 1",
},
{
"_id" : ObjectId("5e0471eb394d1e2b348b94ab"),
"name" : "Venue 2",
}
以及一個地點為 Venue 1 且 ID 為 5e0471e3394d1e2b348b94aa 的 Event 文檔:
{
"_id" : ObjectId("5e04727c76da213f8c9bf76a"),
"eventDate" : ISODate("2019-12-26T11:41:16.019+03:00"),
"name" : "Event 1",
"venue" : ObjectId("5e0471e3394d1e2b348b94aa")
}
當我們要刪除 Venue 1 時,這會導致以下錯誤,因為它有一個事件:
You cannot delete a venue because events are tied to it.
狀態碼為 400。
用 mongoose 和 Expressjs 的 findOneAndDelete 來做:
const express = require("express");
const router = express.Router();
router.delete("/:id", (req, res) => {
if (!mongoose.Types.ObjectId.isValid(req.params.id)) { //checking if id valid
return res.send("Please provide valid id");
}
var id = mongoose.Types.ObjectId(req.params.id); // passing it into a var
Event.findOneAndDelete({ venue: id }).then( res.json({ success: true }));
});
module.exports = router;
詳情https://mongoosejs.com/docs/api/query.html#query_Query-findOneAndDelete
exports.deleteVenue = asyncHandler(async (req, res, next) => {
//First check role. Because it not call database
if (req.user.role !== 'manager' && req.user.role !== 'admin') {
return next(new ErrorResponse(`Not authorized to delete venue`, 401));
}
//Next step, check event
const event = await Event.findById({ venue: ObjectId(req.params.id) });
if (event) {
return next(
new ErrorResponse(
`You cannot delete a venue because events are tied to it.`,
404
)
);
}
//Delete venue by Id
await Venue.deleteOne({ id: req.params.id }, (error, result) =>{
if(error) return next(
new ErrorResponse(`No venue with the id of ${req.params.id}`, 404)
);
res.status(200).json({
success: true,
data: {}
});
})
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.