I am coding an e-commerce site with Node.js.
I noticed some code repeating while creating the routes but I couldn't find how to get rid of it.
men route is given below:
router.get(`/parent-category-selection`,(req, res, next) => {
categoryRequest.getAllParentCategories('mens', (error, data) => {
if(!error){
res.render('category/parentCategorySelection', {parentCategories:data});
}else {
res.render('error', {message:'An error occured.'})
}
})
})
women route is given below:
router.get(`/parent-category-selection`,(req, res, next) => {
categoryRequest.getAllParentCategories('womens', (error, data) => {
if(!error){
res.render('category/parentCategorySelection', {parentCategories:data});
}else {
res.render('error', {message:'An error occured.'})
}
})
})
routes in app.js:
app.use('/', indexRouter);
app.use('/men', menRouter)
app.use('/women',womenRouter)
app.use('/product',productRouter)
I want routes like /women/parent-category-selection and /men/parent-category-selection without code repetition. How can I achieve that as you see above router functions are so similar I should find a way to bind gender information to the router like app.use('/:gender', genderRouter {gender:gender}). Any help ?
CodePudding user response:
One pattern you could use is a higher order function, which is a function that returns a function. In this case, it is used to create an express middleware function. For example:
const parentCategorySelectionHandler = (gender) => (req, res) =>
categoryRequest.getAllParentCategories(gender, (error, data) => {
if (!error) {
res.render("category/parentCategorySelection", {
parentCategories: data,
});
} else {
res.render("error", { message: "An error occured." });
}
});
Which can be used like this:
router.get(`/parent-category-selection`, parentCategorySelectionHandler("men"));
If you wanted to get the gender from the URL, as you suggested, you could change it to the following.
middleware
const parentCategorySelectionHandler = (req, res) =>
categoryRequest.getAllParentCategories(req.params.gender, (error, data) => {
if (!error) {
res.render("category/parentCategorySelection", {
parentCategories: data,
});
} else {
res.render("error", { message: "An error occured." });
}
});
usage
router.get(`/parent-category-selection/:gender`, parentCategorySelectionHandler);
Then you'd need to change how you add the men/women routes in app.js since this one route would cover both of those genders.