為何傳進樣板引擎的變數無法用.key取值?
const url = new Url({
original_url: original_url
});
return url.save()
.then((link) => {
res.render("success", { link });
})
.catch((error) => console.log(error));
奇怪,link確定有傳進success.handlebars,因為可以用{{link}}在頁面上印出link裡面的東西,長這樣:
{
original_url: 'uuu',
_id: new ObjectId("63b152ee75f7725fb76f0fc2"),
__v: 0
}
但為何改成{{link.original_url}}會抓不到東西?
Error message說:
Handlebars: Access has been denied to resolve the property "password" because it is not an "own property" of its parent.
You can add a runtime option to disable the check or this warning:
See https://handlebarsjs.com/api-reference/runtime-options.html#options-to-control-prototype-access for details
原來.save() return回來的promise裡面是Mongoose Document,不是純 json 物件, 所以拿不到物件key值。
聽說有個厲害的.lean()方法可以把Mongoose Document轉成純 json 物件:
const url = new Url({
original_url: original_url
});
return url
.save()
.lean() //加入這行
.then((link) => {
res.render("success", { link });
})
.catch((error) => console.log(error));
Error: TypeError: lean is not a function
怎麼會這樣?!!!!
原來.lean()方法,不支援 .save() 方法!
悲劇。
Solution 1: 只好把要用的東西存成變數,用參數傳進handlebars template
Solution 2: 可是還是想用.lean()把Mongoose Document轉成純 json 物件怎麼辦?
小撇步:先用個.find(), return回來的 Query object 就可以接.lean(), 這樣用handlebars 就抓得到{{link.original_url}} 了!可是這樣多用一個.find()對效率好像不算一件好事…
const url = new Url({
original_url: original_url
});
const id = url._id.toHexString();
return url
.save()
.then(() => {
return Url.findById(id).lean();
})
.then((link) => {
res.render("success", { link });
})
.catch((error) => console.log(error));
Solution 3: 其實還有一個.toObject() 的方法可以把Mongoose Document轉成純 json 物件!
const url = new Url({
original_url: original_url
});
url.save()
.then(()=> {return url.toObject()})
.then((link) => {
res.render("success", { link });
})
.catch((error) => console.log(error));