5
\$\begingroup\$

I have put together a blogging application with Express, EJS and MongoDB.

There is a public, front-end part and a dashboard. In index.js I have:

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

In routes\admin\dashboard.js I have:

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;

I am concerned especially about the controllers "under" the dashboard (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);
    });
}

The controller concerning the categories:

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);
    });
}
\$\endgroup\$

1 Answer 1

2
+50
\$\begingroup\$

Shorthand Property Definition Notation

As I mentioned in an answer to one of your previous posts, The shorthand property definition notation can be used to simplify the lines like these where the key is the same as the name of the variable being referenced:

 categories: categories,
 posts: posts

To simply:

 categories,
 posts

Waiting with await

With async / await the code that is typically in the promise callback can be moved out- so take this section for example:

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

I haven’t tested this code but my presumption is that the call to .populate('category') comes after the callback where res.render() is called - so that may be a bug.

It can be like simplified to something like this:

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

Though maybe the call to populate the category needs to come after the value from Post.find({}) Is assigned to posts.

And similarly for the other functions called with await. This way the value assigned to posts from can be used properly.

Useless else keyword after return

In the callback to post.save():

  if (err) {
      console.log(err);
      return;
  } else {
      req.flash('success', "The post was successfully added");
      req.session.save(() => res.redirect('/dashboard'));
  }

The code in the else block can be moved out because in the first case there is a return statement. This can reduce the indentation level.

variable declared with var

The answer by CertainPerformance to your previous post recommends avoiding the var keyword. Yet this code uses it:

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

     var form = {
         categoryholder: req.body.cat_name
     };

That variable is never reassigned so it can be declared with const. And similarly for updateCategory() - it has a variable declared with var named form that never gets re-assigned.

\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.