Express.js博客应用bug:按类别过滤文章会抛出 "Cast to ObjectId failed "的失败错误。

问题描述 投票:0回答:1

我正在做一个 博客应用 (点击链接查看 GitHub 回购)与 快递, EJS 和MongoDB。

我有 员额 归纳为 岚,巗峃,。,每个人都有自己的收藏。

我遇到了一个问题,试图按类别过滤帖子。为了获得按类别分类的帖子的网址,我把类别名称变成一个slug,然后这样使用。

Posted in <a href="/<%= post.category.cat_name.replace(/\s+/g, '-').toLowerCase(); %>"><%= post.category.cat_name %></a>

在公共路由文件中,我有:

const express = require('express');
const postsController = require('../../controllers/front-end/posts');

// Express router
const router = express.Router();

// Get Posts
router.get('/', postsController.getPosts);

// Get Single Post
router.get('/:id', postsController.getSinglePost);

// Get Posts by Category
router.get('/:catname', postsController.getPostsByCategory);

module.exports = router;

在公共路线文件中,我有: 岗位 模式。

const mongoose = require('mongoose');

const postSchema = new mongoose.Schema({
    title: {
        type: String,
        required: true
    },
    short_description: {
        type: String,
        required: true
    },
    full_text: {
        type: String,
        required: true
    },
    category: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'Category'
    },
    post_image: {
        type: String,
        required: false
    },
    updated_at: {
        type: Date,
        default: Date.now()
    },
    created_at: {
        type: Date,
        default: Date.now()
    }
});

module.exports = mongoose.model('Post', postSchema);

The 种类 模型。

const mongoose = require('mongoose');

const categorySchema = new mongoose.Schema({
    cat_name: {
        type: String,
        required: true
    },
    updated_at: {
        type: Date,
        default: Date.now()
    },
    created_at: {
        type: Date,
        default: Date.now()
    }
});

module.exports = mongoose.model('Category', categorySchema);

在 "帖子 "控制器中,我把slug转回类别名称,以过滤帖子。按类别名称:

exports.getPostsByCategory = (req, res, next) => {

    function titleize(slug) {
            var words = slug.split("-");
            return words.map(function(word) {
                //return word;
                return word.charAt(0).toUpperCase() + word.substring(1).toLowerCase();
            }).join(' ');
        }

    const postCategory = titleize(req.params.catname);

   const posts = Post.find({ cat_name: postCategory }, (err, posts) => {
        console.log('Category: ', postCategory);
        if(err){
            console.log('Error: ', err);
        } else {
            res.render('default/index', {
                moment: moment,
                layout: 'default/layout',
                website_name: 'MEAN Blog',
                page_heading: 'XPress News',
                page_subheading: 'A MEAN Stack Blogging Application',
                posts: posts.reverse(),
            });
        }
    }).populate('category');
};

航线 console.log('Category: ', postCategory) 产出 Category: Favicon.ico 而不是类别名称.

我做错了什么?

javascript node.js express mean-stack
1个回答
1
投票

首先--看看你问DB的时刻--你需要等待答案,所以你应该用 Promise.than()async/await 在你的路由中...另一个从请求中你得到STRING作为参数--但在Mongo模式中你有Object....

所以你应该收到这样的东西 "CastError: Cast to ObjectId failed..."这取决于你的眼光,你可以:首先从以下类别中选择类别。category.db => 所以你收到分类对象后,你可以用这个对象来搜索帖子......,或者你可以先按类别填充帖子的结果(获得简单的类别字段),然后进行进一步的搜索......。


1
投票

category 在您的 post-schema是一个 $refcategory-模式,这就是为什么它拥有一个 objectId. 为了引用和实际查询你的 category-模式,同时使用 .find()你需要先填充它。

Post.
  find({}).
  populate({
    path: 'category',
    match: { cat_name: postCategory}
  }).
  exec((err, posts) => {
    // ...
  });

mongoose文档中的 $ref/populate() 隐秘 此处如果你想知道更多关于它的信息。


1
投票

如果我没看错的话,res是期望json对。

我猜测你的 post.reverse() 不以json格式输出。


0
投票

感谢Lilian Baxan,这里是正确的 getPostsByCategory 方法中 controllers\front-end\posts.js:

const Category = require('../../models/categories');
//more code here

exports.getPostsByCategory = async (req, res, next) => {

    function titleize(slug) {
        var words = slug.split("-");
        return words.map(function(word) {
            //return word;
            return word.charAt(0).toUpperCase() + word.substring(1).toLowerCase();
        }).join(' ');
    }

    const postCategory = titleize(req.params.catname);

    const singleCategory = await Category.findOne({cat_name:postCategory})

    const posts = await Post.find({ category : singleCategory }, (err, posts) => {
        if (err) {
            console.log('Error: ', err);
        } else {
            res.render('default/index', {
                moment: moment,
                layout: 'default/layout',
                website_name: 'MEAN Blog',
                page_heading: 'XPress News',
                page_subheading: 'A MEAN Stack Blogging Application',
                posts: posts.reverse(),
            });
        }
    }).populate('category');
};
© www.soinside.com 2019 - 2024. All rights reserved.