Jack
Jack

Reputation: 491

Mongoose/Node How to access DB in directly in EJS file

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

Answers (1)

Estus Flask
Estus Flask

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

Related Questions