Reputation: 491
I want to access my DB in my EJS header file, which is a partial that is added to every page.
I have a Schema called Category and I want to get the name for the categories which will be in my header dynamically from the db.
I am tring to run the following commmand:
<% Category.find({}, name, function(err, names) { %>
<% if(err) { console.log(err); } %>
<% console.log("Names: " + names); %>
<% }); %>
But of course the header ejs file doesn't have access to Category.
I know normaly to access my DB in a ejs file I query the DB in the route and then pass the data to the ejs, but here since it is the header that will be added to every page I can't really do this operation in the route unless I do it in every route which does seem like such a good idea.
How can I get this data here?
Thanks
Upvotes: 2
Views: 993
Reputation: 222865
Database requests shouldn't be performed directly in view. This is prescribed by separation of concerns principle that stands behind MV* patterns.
Express route handlers act as MVC controllers, their purpose is to provide data from models to views.
Mongoose supports promises, so using callback-based API just complicates everything. Common data like could be provided as a separate function that returns a promise of data, e.g.:
function getPageData() { ... }
async function routeHandler(req, res, next) {
try {
const pageData = await getPageData();
res.render('index', {
...pageData,
/ * etc */
});
} catch (err) {
next(err);
}
};
routeHandler
itself can be refactored to helper function that accepts view, view variables, req
, res
, and next
.
Another approach is to make page data available globally in all or most views with additional middleware, as described in this related question, e.g.:
app.use(async function (req, res, next) {
try {
const pageData = await getPageData();
Object.assign(res.locals, pageData);
next();
} catch (err) {
next(err);
}
});
Upvotes: 2