【问题标题】:How can I access the properties of a populated() database query result in ejs?如何在 ejs 中访问填充()数据库查询结果的属性?
【发布时间】:2018-04-21 14:17:30
【问题描述】:

我试图在前端访问和显示填充数据库查询的结果,但是当我尝试访问填充变量的属性时,我得到了未定义的结果。下面是我的 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 时不会保持这种状态。

Route 文件中的数据库查询和发布请求

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 标签上,quotes[i].submittedBy 返回整个“submittedBy”变量,这意味着 population 方法做了它应该做的事情。但是,如果我尝试访问该对象上的属性,它会返回未定义。引号[i].submittedBy.username 返回未定义。当我检查元素时,submitBy 被引号括起来,所以我认为它现在是一个字符串,出于某种原因。但是,如果我尝试使用 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>
<% } %>

【问题讨论】:

    标签: mongodb express mongoose ejs mongoose-populate


    【解决方案1】:

    您插入实例的方式可能存在错误:

    let quote = new Quote({
       author: req.body.author,
       quote: req.body.quote,
       {$push:{submittedBy: req.body.userId}}
    });
    

    尝试使用它也许这会奏效, 如果它没有给出在渲染之前填充结果后获得的对象的快照。

    你会得到一个提交的数组,所以你不能直接访问用户名,因为在模式中你已经给定了数组类型。

    用大括号代替方括号。

    你可以这样做:

    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
    

    如果您只有一个用户提交报价,现在请按照您所遵循的相同程序忽略答案中的第一个程序。如果多个用户可以提交,那么将是一个数组并相应地访问它。

    【讨论】:

      猜你喜欢
      • 2016-03-12
      • 2013-06-09
      • 2015-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-10
      • 1970-01-01
      相关资源
      最近更新 更多