Search code examples
javascriptnode.jsexpressejsmean-stack

How can I pass Express.js variables to MongoDB functions?


I am working on a blogging application (click the link to see the GitHub repo) with Express, EJS and MongoDB.

I have made a simple pager for the posts.

In the posts controller I have:

exports.getPosts = async (req, res, next) => {

  const posts = await Post.find({}, (err, posts) => {

      const perPage = 10;

      const currPage = req.query.page ? parseInt(req.query.page) : 1;

      const postsCount = posts.length;

      const pageCount = Math.ceil(postsCount / perPage);

      const pageDecrement = currPage > 1 ? 1 : 0;

      const pageIncrement = currPage < pageCount ? 1 : 0;

      if (err) {
        console.log("Error: ", err);
      } else {
        res.render("default/index", {
          moment: moment,
          layout: "default/layout",
          website_name: "MEAN Blog",
          page_heading: "XPress News",
          page_subheading: "A MEAN Stack Blogging Application",
          currPage: currPage,
          pageDecrement: pageDecrement,
          pageIncrement: pageIncrement,
          posts: posts,
        });
      }
    })
      .sort({ created_at: -1 })
      .populate("category")
      .limit(perPage)
      .skip((currPage - 1) * perPage);
};

The pager in the view:

<% if (posts) {%>
  <div class="clearfix d-flex justify-content-center">
    <div class="px-1">
        <a class="btn btn-primary <%= pageDecrement == 0 ? 'disabled' : '' %>" href="/?page=<%= currPage - pageDecrement %>">&larr; Newer Posts</a>
    </div>

    <div class="px-1">
        <a class="btn btn-primary <%= pageIncrement == 0 ? 'disabled' : '' %>" href="/?page=<%= currPage + pageIncrement %>">Older Posts &rarr;</a>
    </div>
  </div>
<% } %>

The problem

The line .limit(perPage) from the controller gives the error perPage is not defined in the console (Git bash).

The solution that does not work

Clearly, I can move these 2 lines above const posts

const perPage = 5;
const currPage = req.query.page ? parseInt(req.query.page) : 1;

but I can not do the same with const postsCount = posts.length; (which I also need in the view).

The objective

I am trying to make the snippet of code regarding the pagination reusable (like a plugin, if possible), since I need to paginate for the posts filtered by category, and also the list of post in the admin section o the application.

What am I doing wrong?


Solution

  • why are you using callback and await together.seems like you need to look in to async / await and promises.What you can do is as below:

    exports.getPosts = async (req, res, next) => {
      const currPage = req.query.page ? parseInt(req.query.page) : 1;
      const perPage = 10;
      try {
        const posts = await Post.find({})
          .sort({ created_at: -1 })
          .populate("category")
          .limit(perPage)
          .skip((currPage - 1) * perPage).exec();
    
        const postsCount = posts.length;
    
        const pageCount = Math.ceil(postsCount / perPage);
    
        const pageDecrement = currPage > 1 ? 1 : 0;
    
        const pageIncrement = currPage < pageCount ? 1 : 0;
        res.render("default/index", {
          moment: moment,
          layout: "default/layout",
          website_name: "MEAN Blog",
          page_heading: "XPress News",
          page_subheading: "A MEAN Stack Blogging Application",
          currPage: currPage,
          pageDecrement: pageDecrement,
          pageIncrement: pageIncrement,
          posts: posts,
        });
      } catch (err) {
        console.log("Error: ", err);
        // add proper error handling here 
        res.render('default/error', {
          err
        });
      }
    };