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?
4 Réponses :
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.
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
si je lis ceci correctement, res est attendu des paires json.
Je suppose que votre post.reverse ()
ne sort pas au format json.
post.reverse ()
renvoie un objet JavaScript.
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 ...
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 >