Application de blogs Express.js
J'ai mis en place cette application de blogging avec Express , EJS et MongoDB.
Il y a une partie frontale publique et un tableau de bord. Dans index.js, j'ai:
// Bring the Dashboard
const dashboardRoute = require("./routes/admin/dashboard");
// Register Dashboard Routes
app.use('/dashboard', dashboardRoute);
// Bring the Posts Routes
const postsRoute = require('./routes/front-end/posts');
// Register Posts Routes
app.use('/', postsRoute);
Dans routes\admin\dashboard.jsj'ai:
const express = require('express');
const imageUploader = require('../../utils/imageupload.js');
const validator = require('../../utils/validation.js');
const dashboardController = require('../../controllers/admin/dashboard');
const categoriesController = require('../../controllers/admin/categories');
// Express router
const router = express.Router();
// Display Dashboard
router.get('/', dashboardController.displayDashboard);
// Render add Post Form
router.get('/addpost', dashboardController.addPostForm);
// Add Post
router.post('/post/add', imageUploader.upload, validator.addPostCheck, dashboardController.addPost);
// Edit Post
router.get('/post/edit/:id', dashboardController.editPost);
// Update Post
router.post('/post/update/:id', imageUploader.upload, validator.addPostCheck, dashboardController.updatePost);
// Delete Post
router.delete('/post/delete/:id', dashboardController.deletePost);
// Display Categories
router.get('/categories', categoriesController.showCategories);
// Render add Categories Form
router.get('/categories/addcategory', categoriesController.addCategoryForm);
// Add Category
router.post('/category/add', validator.addCategoryCheck, categoriesController.addCategory);
// Edit Post
router.get('/category/edit/:id', categoriesController.editCategory);
// Update Category
router.post('/category/update/:id', validator.addCategoryCheck, categoriesController.updateCategory);
// Delete Category
router.delete('/category/delete/:id', categoriesController.deleteCategory);
module.exports = router;
Je suis particulièrement préoccupé par les contrôleurs "sous" le tableau de bord ( controllers\admin\dashboard.js):
const Post = require('../../models/post');
const Category = require('../../models/categories');
const {upload} = require('multer');
const {validationResult} = require('express-validator');
exports.displayDashboard = async (req, res, next) => {
const posts = await Post.find({}, (err, posts) => {
if (err) {
console.log('Error: ', err);
} else {
res.render('admin/index', {
layout: 'admin/layout',
website_name: 'MEAN Blog',
page_heading: 'Dashboard',
posts: posts
});
}
}).populate('category');
};
exports.addPostForm = async (req, res, next) => {
const categories = await Category.find({}, (err, categories) => {
if (err) {
console.log('Error: ', err);
} else {
res.render('admin/addpost', {
layout: 'admin/layout',
website_name: 'MEAN Blog',
page_heading: 'Dashboard',
page_subheading: 'Add New Post',
categories: categories
});
}
});
}
exports.addPost = (req, res, next) => {
const form = {
titleholder: req.body.title,
excerptholder: req.body.excerpt,
bodyholder: req.body.body
};
const errors = validationResult(req);
const post = new Post();
post.title = req.body.title;
post.short_description = req.body.excerpt
post.full_text = req.body.body;
post.category = req.body.category;
if (req.file) {
post.post_image = req.file.filename;
}
if (!errors.isEmpty()) {
const categories = Category.find({}, (err, categories) => {
req.flash('danger', errors.array())
res.render('admin/addpost', {
layout: 'admin/layout',
website_name: 'MEAN Blog',
page_heading: 'Dashboard',
page_subheading: 'Add New Post',
categories: categories,
form: form
});
});
} else {
post.save(function(err) {
if (err) {
console.log(err);
return;
} else {
req.flash('success', "The post was successfully added");
req.session.save(() => res.redirect('/dashboard'));
}
});
}
}
exports.editPost = async (req, res, next) => {
const postId = req.params.id;
Post.findById(postId, function(err, post) {
const categories = Category.find({}, (err, categories) => {
if (err) {
console.log('Error: ', err);
} else {
res.render('admin/editpost', {
layout: 'admin/layout',
website_name: 'MEAN Blog',
page_heading: 'Dashboard',
page_subheading: 'Edit Post',
categories: categories,
post: post
});
}
});
});
}
exports.updatePost = (req, res, next) => {
const query = {
_id: req.params.id
}
const form = {
titleholder: req.body.title,
excerptholder: req.body.excerpt,
bodyholder: req.body.body
};
const errors = validationResult(req);
const post = {};
post._id = req.params.id;
post.title = req.body.title;
post.short_description = req.body.excerpt
post.full_text = req.body.body;
post.category = req.body.category;
if (req.file) {
post.post_image = req.file.filename;
}
if (!errors.isEmpty()) {
req.flash('danger', errors.array());
const categories = Category.find({}, (err, categories) => {
res.render('admin/editpost', {
layout: 'admin/layout',
website_name: 'MEAN Blog',
page_heading: 'Dashboard',
page_subheading: 'Edit Post',
categories: categories,
form: form,
post: post
});
});
} else {
Post.update(query, post, function(err) {
if (err) {
console.log(err);
return;
} else {
req.flash('success', "The post was successfully updated");
req.session.save(() => res.redirect('/dashboard'));
}
});
}
}
exports.deletePost = (req, res, next) => {
const postId = req.params.id;
Post.findByIdAndRemove(postId, function(err) {
if (err) {
console.log('Error: ', err);
}
res.sendStatus(200);
});
}
Le responsable du traitement concernant les catégories :
const Category = require('../../models/categories');
const { validationResult } = require('express-validator');
exports.showCategories = async (req, res, next) => {
const categories = await Category.find({}, (err, categories) => {
if(err){
console.log('Error: ', err);
} else {
res.render('admin/categories', {
layout: 'admin/layout',
website_name: 'MEAN Blog',
page_heading: 'Dashboard',
page_subheading: 'Categories',
categories: categories
});
}
});
};
exports.addCategoryForm = (req, res, next) => {
res.render('admin/addcategory', {
layout: 'admin/layout',
website_name: 'MEAN Blog',
page_heading: 'Dashboard',
page_subheading: 'Add New Category',
});
}
exports.addCategory = (req, res, next) => {
var form = {
categoryholder: req.body.cat_name
};
const errors = validationResult(req);
const category = new Category();
category.cat_name = req.body.cat_name;
if (!errors.isEmpty()) {
req.flash('danger', errors.array())
res.render('admin/addcategory',{
layout: 'admin/layout',
website_name: 'MEAN Blog',
page_heading: 'Dashboard',
page_subheading: 'Add New Category',
form:form
}
);
} else {
category.save(function(err) {
if (err) {
console.log(err);
return;
} else {
req.flash('success', "The category was successfully added");
req.session.save(() => res.redirect('/dashboard/categories'));
}
});
}
}
exports.editCategory = (req, res, next) => {
const catId = req.params.id;
Category.findById(catId, function(err, category){
if (err) {
console.log('Error: ', err);
} else {
res.render('admin/editcategory', {
layout: 'admin/layout',
website_name: 'MEAN Blog',
page_heading: 'Dashboard',
page_subheading: 'Edit Category',
category: category
});
}
});
}
exports.updateCategory = (req, res, next) => {
const query = {_id:req.params.id}
var form = {
categoryholder: req.body.cat_name
};
const errors = validationResult(req);
const category = {};
category._id = req.params.id;
category.cat_name = req.body.cat_name;
if (!errors.isEmpty()) {
req.flash('danger', errors.array())
res.render('admin/editcategory',{
layout: 'admin/layout',
website_name: 'MEAN Blog',
page_heading: 'Dashboard',
page_subheading: 'Edit Category',
form: form,
category: category
}
);
} else {
Category.update(query, category, function(err){
if(err){
console.log(err);
return;
} else {
req.flash('success', "The category was successfully updated");
req.session.save(() => res.redirect('/dashboard/categories'));
}
});
}
}
exports.deleteCategory = (req, res, next) => {
const catId = req.params.id;
Category.findByIdAndRemove(catId, function(err){
if (err) {
console.log('Error: ', err);
}
res.sendStatus(200);
});
}
Réponses
Notation de définition de propriété abrégée
Comme je l'ai mentionné dans une réponse à l'un de vos articles précédents, la notation de définition de propriété abrégée peut être utilisée pour simplifier les lignes comme celles-ci où la clé est la même que le nom de la variable référencée:
categories: categories, posts: posts
Pour simplement:
categories,
posts
En attendant avec await
Avec async / await, le code qui est généralement dans le rappel de promesse peut être déplacé vers l'extérieur - prenez donc cette section par exemple:
const posts = await Post.find({}, (err, posts) => { if (err) { console.log('Error: ', err); } else { res.render('admin/index', { layout: 'admin/layout', website_name: 'MEAN Blog', page_heading: 'Dashboard', posts: posts }); } }).populate('category');
Je n'ai pas testé ce code mais je suppose que l'appel à .populate('category')vient après le rappel où res.render()est appelé - donc cela peut être un bogue .
Cela peut être comme simplifié à quelque chose comme ceci:
const posts = await Post.find({}).populate('category').catch(err => {
console.log('Error: ', err);
});
res.render('admin/index', {
layout: 'admin/layout',
website_name: 'MEAN Blog',
page_heading: 'Dashboard',
posts
});
Bien que l'appel de remplissage de la catégorie doive peut-être venir après la valeur de Post.find({})Est assignée à posts.
Et de même pour les autres fonctions appelées avec await. De cette façon, la valeur attribuée à postsfrom peut être utilisée correctement.
elseMot-clé inutile aprèsreturn
Dans le rappel à post.save():
if (err) { console.log(err); return; } else { req.flash('success', "The post was successfully added"); req.session.save(() => res.redirect('/dashboard')); }
Le code du elsebloc peut être déplacé car dans le premier cas, il y a une returninstruction. Cela peut réduire le niveau d'indentation.
variable déclarée avec var
La réponse de CertainPerformance à votre article précédent recommande d'éviter le varmot - clé. Pourtant ce code l'utilise:
exports.addCategory = (req, res, next) => { var form = { categoryholder: req.body.cat_name };
Cette variable n'est jamais réaffectée et peut donc être déclarée avec const. Et de même pour updateCategory()- il a une variable déclarée avec varnamed formqui n'est jamais réaffectée.