如何在 ejs 中访问 populated() 数据库查询结果的属性?
How can I access the properties of a populated() database query result in ejs?
我试图在前端访问和显示填充的数据库查询的结果,但是当我尝试访问填充的变量的属性时,我得到了未定义的结果。下面是我的 mongoose find 方法引用的模式。
报价架构
const express = require('express')
const mongoose = require('mongoose')
const Schema = mongoose.Schema
const User = require('../models/users')
let QuoteSchema = new Schema({
author: {
type: String,
trim: true
},
quote: {
type: String,
unique: [true, "this quote already exists."],
trim: true
},
submittedBy: [{
type: Schema.Types.ObjectId,
ref: 'users'
// trim: true,
// required: true
}]
}, {
timestamps: true
})
const Quote = mongoose.model('quotes', QuoteSchema)
module.exports = Quote
用户架构
const express = require('express')
const mongoose = require('mongoose')
const Schema = mongoose.Schema
let UserSchema = new Schema ({
username: {
type: String,
unique: [true, "This username is taken."],
trim: true,
},
email: {
type: String,
unique: [true, "This email is already being used."],
trim: true
},
password: {
type: String,
trim: true
},
favorites: []
}, {
timestamps: true,
})
const User = mongoose.model('users', UserSchema)
module.exports = User
这是猫鼬查询。 populate 方法附加到 find 方法,sort 方法附加到 populate 方法。结果的typeof确认它是一个对象,但我认为当它到达ejs时它不会保持这种状态。
数据库查询和post路由文件中的请求
router.get('/', (req, res, next) => {
console.log("beginning query...")
const flashMessages = res.locals.getMessages()
if (req.user) {
Quote.find({}).populate('submittedBy').sort({ _id: -1 })
.exec((err, results) => {
console.log(typeof results) // returns "object"
err ? console.log(err) : res.render('index', { quotes: results, user: req.user, csrfToken: req.csrfToken() });
})
}
})
router.post('/quotes', (req, res, next) => {
if(req.isAuthenticated()) {
let quote = new Quote({
author: req.body.author,
quote: req.body.quote,
submittedBy: req.body.userId
})
quote.save((err, quote) => {
if (err) {
console.log(err)
} else {
console.log("Added the quote \"" + quote.quote + "\" by " + quote.author + ".")
res.redirect('/')
}
})
.catch(next)
} else {
req.flash("restricted", "You must first login before you can add quotes to the community feed.")
res.redirect('/')
}
})
我认为这是发生错误的地方。在最后一个 span 标签上,引用 [i].submittedBy returns 整个 "submittedBy" 变量,这意味着 population 方法做了它应该做的。但是,如果我尝试访问该对象上的 属性,它 returns 未定义。引号[i].submittedBy.username returns 未定义。当我检查元素时,submitted 被引号包围,所以我认为出于某种原因现在它是一个字符串。但是如果我尝试使用 JSON.parse() 或 JSON.stringify(),我在这两种情况下都会出错。我不知道该怎么办。请帮忙!
Ejs 渲染
<% for(var i = 0; i < quotes.length; i++) {%>
<li class="quote">
<i class="fa fa-close fa-quote-close move hidden"></i>
<i class="fa fa-heart hidden"></i>
<span class="make-bold nhauthorValues" id="<%= quotes[i]._id %>" contenteditable="true"><%= quotes[i].author %></span> once said: "<span class="quoteValues" id="<%= quotes[i]._id %>" contenteditable="true"><%= quotes[i].quote %></span>"
<span class="by"><%= quotes[i].submittedBy.username %></span>
</li>
<% } %>
您插入实例的方式可能有误:
let quote = new Quote({
author: req.body.author,
quote: req.body.quote,
{$push:{submittedBy: req.body.userId}}
});
尝试使用这个也许会奏效,
如果它不提供您在渲染之前填充结果后获得的对象的快照。
你会得到一个 submittedBy 数组,所以你不能直接访问用户名,因为在模式中你已经给定了数组类型。
使用大括号代替方括号。
你可以这样做:
const express = require('express')
const mongoose = require('mongoose')
const Schema = mongoose.Schema
const User = require('../models/users')
let QuoteSchema = new Schema({
author: {
type: String,
trim: true
},
quote: {
type: String,
unique: [true, "this quote already exists."],
trim: true
},
submittedBy: {
type: Schema.Types.ObjectId,
ref: 'users'
// trim: true,
// required: true
} //removed square brackets
}, {
timestamps: true
})
const Quote = mongoose.model('quotes', QuoteSchema)
module.exports = Quote
现在,如果您只有一个用户提交报价,请按照与之前相同的步骤进行操作,忽略答案中的第一个步骤。如果多个用户可以然后 submittBy 将是一个数组并相应地访问它。
我试图在前端访问和显示填充的数据库查询的结果,但是当我尝试访问填充的变量的属性时,我得到了未定义的结果。下面是我的 mongoose find 方法引用的模式。
报价架构
const express = require('express')
const mongoose = require('mongoose')
const Schema = mongoose.Schema
const User = require('../models/users')
let QuoteSchema = new Schema({
author: {
type: String,
trim: true
},
quote: {
type: String,
unique: [true, "this quote already exists."],
trim: true
},
submittedBy: [{
type: Schema.Types.ObjectId,
ref: 'users'
// trim: true,
// required: true
}]
}, {
timestamps: true
})
const Quote = mongoose.model('quotes', QuoteSchema)
module.exports = Quote
用户架构
const express = require('express')
const mongoose = require('mongoose')
const Schema = mongoose.Schema
let UserSchema = new Schema ({
username: {
type: String,
unique: [true, "This username is taken."],
trim: true,
},
email: {
type: String,
unique: [true, "This email is already being used."],
trim: true
},
password: {
type: String,
trim: true
},
favorites: []
}, {
timestamps: true,
})
const User = mongoose.model('users', UserSchema)
module.exports = User
这是猫鼬查询。 populate 方法附加到 find 方法,sort 方法附加到 populate 方法。结果的typeof确认它是一个对象,但我认为当它到达ejs时它不会保持这种状态。
数据库查询和post路由文件中的请求
router.get('/', (req, res, next) => {
console.log("beginning query...")
const flashMessages = res.locals.getMessages()
if (req.user) {
Quote.find({}).populate('submittedBy').sort({ _id: -1 })
.exec((err, results) => {
console.log(typeof results) // returns "object"
err ? console.log(err) : res.render('index', { quotes: results, user: req.user, csrfToken: req.csrfToken() });
})
}
})
router.post('/quotes', (req, res, next) => {
if(req.isAuthenticated()) {
let quote = new Quote({
author: req.body.author,
quote: req.body.quote,
submittedBy: req.body.userId
})
quote.save((err, quote) => {
if (err) {
console.log(err)
} else {
console.log("Added the quote \"" + quote.quote + "\" by " + quote.author + ".")
res.redirect('/')
}
})
.catch(next)
} else {
req.flash("restricted", "You must first login before you can add quotes to the community feed.")
res.redirect('/')
}
})
我认为这是发生错误的地方。在最后一个 span 标签上,引用 [i].submittedBy returns 整个 "submittedBy" 变量,这意味着 population 方法做了它应该做的。但是,如果我尝试访问该对象上的 属性,它 returns 未定义。引号[i].submittedBy.username returns 未定义。当我检查元素时,submitted 被引号包围,所以我认为出于某种原因现在它是一个字符串。但是如果我尝试使用 JSON.parse() 或 JSON.stringify(),我在这两种情况下都会出错。我不知道该怎么办。请帮忙!
Ejs 渲染
<% for(var i = 0; i < quotes.length; i++) {%>
<li class="quote">
<i class="fa fa-close fa-quote-close move hidden"></i>
<i class="fa fa-heart hidden"></i>
<span class="make-bold nhauthorValues" id="<%= quotes[i]._id %>" contenteditable="true"><%= quotes[i].author %></span> once said: "<span class="quoteValues" id="<%= quotes[i]._id %>" contenteditable="true"><%= quotes[i].quote %></span>"
<span class="by"><%= quotes[i].submittedBy.username %></span>
</li>
<% } %>
您插入实例的方式可能有误:
let quote = new Quote({
author: req.body.author,
quote: req.body.quote,
{$push:{submittedBy: req.body.userId}}
});
尝试使用这个也许会奏效, 如果它不提供您在渲染之前填充结果后获得的对象的快照。
你会得到一个 submittedBy 数组,所以你不能直接访问用户名,因为在模式中你已经给定了数组类型。
使用大括号代替方括号。
你可以这样做:
const express = require('express')
const mongoose = require('mongoose')
const Schema = mongoose.Schema
const User = require('../models/users')
let QuoteSchema = new Schema({
author: {
type: String,
trim: true
},
quote: {
type: String,
unique: [true, "this quote already exists."],
trim: true
},
submittedBy: {
type: Schema.Types.ObjectId,
ref: 'users'
// trim: true,
// required: true
} //removed square brackets
}, {
timestamps: true
})
const Quote = mongoose.model('quotes', QuoteSchema)
module.exports = Quote
现在,如果您只有一个用户提交报价,请按照与之前相同的步骤进行操作,忽略答案中的第一个步骤。如果多个用户可以然后 submittBy 将是一个数组并相应地访问它。