【问题标题】:Mongoose query returning in Node/Express CRUD API在 Node/Express CRUD API 中返回的 Mongoose 查询
【发布时间】:2016-01-25 12:19:04
【问题描述】:

它适用于大多数情况下 admin.js 路由,但是 .put() 和 delete() 请求的底部附近的 .get() 请求可以正确呈现,并且数据在页面上可见,但是在我的终端收到此错误

... /admin.js:91 res.render('admin', {title: post.title, body: post.body}); ^

TypeError: 无法读取 null 的属性“标题”

尝试编辑或删除表单上呈现的帖子时,我收到“此网页不可见”错误。所以它渲染得很好然后崩溃了。

这里是 admin.js 路由。可能是订购的问题?我不明白为什么会崩溃。

var express = require('express');
var router = express.Router();
var session = require('client-sessions');
var bcrypt = require('bcryptjs');

var mongoose = require('mongoose');
var User = mongoose.model('users');
var Post = mongoose.model('posts');
var Song = mongoose.model('songs');
var Project = mongoose.model('projects');

// check whether User is logged in
function requireLogin(req, res, next) {
    if (!req.user) {
        req.session.reset();
        res.redirect('/admin');
    } else {
        next();
    }
};

router
    // Register
    .get('/register', requireLogin, function(req, res) {
        res.render('register');
    })

    .post('/register', function(req, res) {
        new User({
            name: req.body.name,
            password: req.body.password
        })
        .save(function(err, user) {
            res.redirect('/admin');
        });
    })

    // Login
    .get('/', function(req, res) {
        res.render('login');
    })

    .post('/', function(req, res) {
        User.findOne({name: req.body.name}, function(err, user) {
            if (!user) {
                res.render('login', {error: 'User not found'});
            } else if (bcrypt.compareSync(req.body.password, user.password)) {
                req.session.user = user;
                res.redirect('/admin/dashboard');
            } else {
                res.render('login', {error: 'Incorrect Password'});
            }
        });
    })  

    // Admin dashboard
    .get('/dashboard', requireLogin, function(req, res) {
        res.render('admin');
    })

    .post('/dashboard', function(req, res) {
        // Depending on which form was filled, create new entry and redirect
        if (req.body.postTitle) {
            new Post({title: req.body.postTitle, body: req.body.body})
            .save(function(err, post) {
                res.redirect('/posts');
            });
        } else if (req.body.songTitle) {
            new Song({title: req.body.songTitle, arist: req.body.artist, link: req.body.link})
            .save(function(err, song) {
                res.redirect('/music');
            });
        } else if (req.body.projectName) {
            new Project({
                name: req.body.projectName,
                picture: req.body.picture,
                languages: req.body.languages,
                summary: req.body.summary
            })
            .save(function(err, project) {
                res.redirect('/projects');
            });
        } else {
            res.redirect('/');
        }
    })

    .get('/dashboard/:title_slug', function(req, res) {
        var query = {'title_slug': req.params.title_slug};
        Post.findOne(query, function(err, post) {
            res.render('admin', {title: post.title, body: post.body});
        });
    })

    .put('/dashboard/:title_slug', function(req, res) {
        var query = {'title_slug': req.params.title_slug};
        var update = {'title': req.params.title, 'body': req.params.body};
        var options = {new: true};
        Post.findOneAndUpdate(query, update, options, function(err, post) {
            res.render('admin', 
                {
                    title: post.title,
                    body: post.body
                }
            );
        });
    })

    .delete('/dashboard/:title_slug', function(req, res) {
        var query = {'title_slug': req.params.title_slug};
        Post.findOneAndRemove(query, function(err, post) {
            res.redirect('/');
        });
    })

    // Logout
    .get('/logout', function(req, res) {
        req.session.reset();
        res.redirect('/admin');
    });

module.exports = router;

admin.html 中 DELETE 请求的表单示例

<div class='form posts-form'>
    <h2>Posts</h2>
    <form method='post' id='post' action'/admin/dashboard/{{post.title_slug}}?_method=DELETE'>
        <label>Title</label>
        <input type='text' name='postTitle' value='{{title}}'></br>
        <label>Body</label>
        <textarea name='body' form='post'>{{body}}</textarea></br>
        <button type='submit'>Delete</button>
    </form> 
</div>

【问题讨论】:

    标签: javascript node.js mongodb express mongoose


    【解决方案1】:

    同时检查 if(!post){ console.log("no post found")}。因为看起来没有找到任何项目,而您正在尝试获取未创建对象的标题。

    Post.findOne(query, function(err, post) {
        if (err)
           console.log(err);
        if (!post)
           console.log("not found")
        else
           res.render('admin', {title: post.title, body: post.body});
    });
    

    【讨论】:

    • 感谢您的建议。奇怪,包括 if (!post) 没有输出任何错误,但是之前的 Type Error 现在已经消失了。因此,虽然功能上没有任何变化,也没有任何新的错误消息,但原来的错误消息现在已经消失了。
    • 但控制台打印“未找到”?看起来现在您没有输入 else 案例,因此不会引发错误
    • Restarted nodemon and now 'not found' 确实被抛出,即使帖子以编辑和删除的形式正确呈现。它以某种方式找到要渲染的帖子,但仍然找不到。奇怪
    • 你检查过你的 req.params.title_slug 可能是不对的试试 consol.log(req.params.title_slug)
    • 是的,标题 slug 是正确的,它可以很好地检索帖子以填充表单数据。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-16
    • 2021-06-19
    • 2019-08-29
    • 2021-03-16
    • 1970-01-01
    • 2015-06-16
    • 1970-01-01
    相关资源
    最近更新 更多