1
votes

Bogue de l'application de blog Express.js: le filtrage des articles par catégorie génère l'erreur "Cast to ObjectId failed"

Je travaille sur une application de blog (cliquez sur le lien vers voir le dépôt GitHub ) avec Express , EJS et MongoDB.

J'ai des messages regroupés en catégories , chacun dans sa propre collection .

Je rencontre un problème en essayant de filtrer les messages par catégorie. Pour obtenir le message par URL de catégorie, je transforme le nom de la catégorie en slug et l'utilise de cette façon:

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');
};

Dans le fichier de routes publiques que j'ai:

XXX

Le modèle Post :

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);

Le modèle Catégorie : p >

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);

Dans le contrôleur de messages, je transforme le slug en nom de catégorie pour filtrer les messages par nom de catégorie :

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;

La ligne console.log ('Category:', postCategory) renvoie Category: Favicon.ico au lieu du nom de la catégorie .

Qu'est-ce que je fais de mal?


0 commentaires

4 Réponses :


1
votes

category dans votre post -schema est un $ ref à la category -schema, c'est pourquoi il contient un objectId . Pour référencer et interroger votre schéma de catégorie tout en utilisant .find () , vous devez d'abord le renseigner:

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

La documentation mangouste pour $ ref / populate () est un peu cachée ici a>, au cas où vous voudriez en savoir plus.


2 commentaires

J'ai besoin d'une liste d'articles, pas d'un seul article. Et ce sont des articles pas d'histoires.


Modifiez-le pour trouver au lieu de findOne



1
votes

si je lis ceci correctement, res est attendu des paires json.

Je suppose que votre post.reverse () ne sort pas au format json.


1 commentaires

post.reverse () renvoie un objet JavaScript.



1
votes

tout d'abord - regardez le moment où vous demandez à DB - vous devez attendre la réponse, vous devez donc utiliser Promise.than () ou async / await dans vos itinéraires ... Un autre de la requête, vous obtenez STRING comme paramètre - mais dans le schéma mongo, vous avez Object ...

Vous devriez donc recevoir un message comme "CastError: Cast to ObjectId failed ..." , cela dépend de votre vision, vous pouvez: d'abord sélectionner la catégorie dans category.db => afin de recevoir la catégorie Objet après cela, vous pouvez rechercher les messages en utilisant cet objet ..., ou vous pouvez d'abord remplir les résultats de articles par catégorie (obtenir des champs de catégorie simples) et faire une recherche plus approfondie ...


0 commentaires

0
votes

Merci à Lilian Baxan, voici la bonne méthode getPostsByCategory dans 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');
};

p >


0 commentaires