express-inventory-application/controllers/category.js
2023-09-09 18:47:17 -07:00

168 lines
4.9 KiB
JavaScript

const Category = require("../models/category.js");
const Item = require("../models/item.js");
const asyncHandler = require("express-async-handler");
const { body, validationResult } = require("express-validator");
exports.index = asyncHandler(async (req, res, next) => {
// get array of relevant variables for displaying category and its items
// get current category from URL
const category = await Category.findOne({
simpleName: req.params.category,
})
.lean()
.exec();
// check
if (category === null) {
const error = new Error("Category not found");
return next(error);
}
// get all items from category
const items = await Item.find({ category: category._id }).lean().exec();
// render with all relevant vars
res.render("category", {
category: category,
items: items,
});
});
exports.category_create_get = (req, res, next) => {
res.render("createcategory");
};
exports.category_create_post = [
// Validate and sanitize name
body("name", "Category must have a name!")
.trim()
.isLength({ min: 1 })
.escape(),
// Validate and sanitize description
body("description", "Category must have a description!")
.trim()
.isLength({ min: 1 })
.escape(),
// Process request after validation and sanitization.
asyncHandler(async (req, res, next) => {
// Extract the validation errors from a request.
const errors = validationResult(req);
// Create a new category with escaped and trimmed data.
const category = new Category({
name: req.body.name,
simpleName: req.body.name.toLowerCase().replace(" ", ""),
description: req.body.description,
});
// if there are validation errors
if (!errors.isEmpty()) {
// Render the creation form again with sanitized values/error messages.
res.render("createcategory", {
errors: errors.array(),
});
return;
}
// Data from form is valid.
else {
// Check if Category with same name already exists.
const categoryExists = await Category.findOne({
name: req.body.name,
}).exec();
if (categoryExists) {
// Category exists, redirect to its page.
res.redirect(`/${categoryExists.simpleName}`);
}
// else category is unique
else {
await category.save();
// saved. Redirect to new category page.
res.redirect(`/${category.simpleName}`);
}
}
}),
];
exports.category_delete_get = asyncHandler(async (req, res, next) => {
// get current category from URL
const category = await Category.findOne({
simpleName: req.params.category,
})
.lean()
.exec();
// check
if (category === null) {
const error = new Error("Category not found");
return next(error);
}
// else, continue to find all relevant items (if any)
const items = await Item.find({ category: category._id }).lean().exec();
// if items found
if (items.length > 0) {
// delete all items from db - for loop used for practicality reasons (forEach() doesn't play well with async)
for (let i = 0; i < items.length; i++) {
const itemID = items[i]._id;
await Item.findByIdAndDelete(itemID);
}
}
// delete category
await Category.findByIdAndDelete(category._id);
// redirects to Home
res.redirect("/");
});
exports.category_update_get = asyncHandler(async (req, res, next) => {
// get current category from URL
const category = await Category.findOne({
simpleName: req.params.category,
})
.lean()
.exec();
res.render("editcategory", { category: category });
});
exports.category_update_post = [
// Validate and sanitize name
body("name", "Category must have a name!")
.trim()
.isLength({ min: 1 })
.escape(),
// Validate and sanitize description
body("description", "Category must have a description!")
.trim()
.isLength({ min: 1 })
.escape(),
// Process request after validation and sanitization.
asyncHandler(async (req, res, next) => {
// Extract the validation errors from a request.
const errors = validationResult(req);
// find existing category in database
const dbCat = await Category.findOne({ simpleName: req.params.category })
.lean()
.exec();
// Create a new category with escaped and trimmed data.
const category = new Category({
name: req.body.name,
simpleName: req.body.name.toLowerCase().replace(" ", ""),
description: req.body.description,
_id: dbCat._id, // copy original category ID to prevent overwrite errors
});
// if there are validation errors
if (!errors.isEmpty()) {
// Render the creation form again with sanitized values/error messages.
res.render("editcategory", {
category: dbCat,
});
return;
}
// Data from form is valid.
else {
await Category.findByIdAndUpdate(dbCat._id, category, {});
res.redirect(`/${category.simpleName}`);
}
}),
];