How to implement pagination with mongoose and EJS and keep the search query when paging?

Im using Nodejs, EJS, Mongoose and MongoDB and i have a table that is created from the documents in my DB and cant get paging buttons to work without clearing my search query.

The way my app works is

  1. Click on the search link which opens a search filter page. My Search page

  2. Then you select you filer and search. Results are then shown. With Search Query in URL Searched Results with Search Query

3.When you click on the next page it clears your query. Page buttons

Here is my paging buttons and below is my route My search filters are on another page.

<div class="container">
  <nav aria-label="...">
    <ul class="pagination float-right">
      <li class="page-item disabled">
        <span class="page-link">Previous</span>
      </li>
      <li class="page-item active">
        <a class="page-link" name="1" href="/searched/1">1</a>
      </li>
      <li class="page-item">
        <a class="page-link" name="2" href="/searched/2">2</a>
      </li>
      <li class="page-item">
        <a class="page-link" name="3" href="/searched/3">3</a>
      </li>
      <li class="page-item">
        <a class="page-link">Next</a>
      </li>
    </ul>
  </nav>
</div>

app.get("/searched/:page/:limit", function (req, res) {
  if (req.isAuthenticated()) {
    // const { page, limit } = req.params;

    // const options = {
    //   sort: { dateAdded: -1 },
    //   page: page,
    //   limit: limit,
    // };

    const query = req.query;

    if (query.btu === "") {
      delete query.btu;
    }

    if (query.sn1 === "") {
      delete query.sn1;
    }

    if (query.sn2 === "") {
      delete query.sn2;
    }

    if (query.userCreated === "") {
      delete query.userCreated;
    }

    if (query.split === "") {
      delete query.split;
    }

    if (query.supplier === "") {
      delete query.supplier;
    }

    if (query.issued === "") {
      delete query.issued;
    }

    // Aircon.paginate(query, options, function (err, foundAircons) {
    //   if (err) {
    //     console.log(err);
    //   } else {
    //     console.log(foundAircons);
    //     res.render("instock", {
    //       foundAircons: foundAircons.docs,
    //     });
    //   }
    // });

    Aircon.find(query)
      .sort({
        dateAdded: "desc",
      })
      .exec((err, foundAircons) => {
        if (err) {
          console.log(err);
        } else {
          res.render("instock", {
            foundAircons: foundAircons,
          });
        }
      });
  } else {
    res.redirect("/login");
  }
});

Answers 1

  • managed to get it working as well with mongoose paginate v2 and found a function to rebuild the query string and pass back to the buttons

    function objectToQueryString(obj) {
      var str = [];
      for (var p in obj)
        if (obj.hasOwnProperty(p)) {
          str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
        }
      return str.join("&");
    }
    
    
    app.get("/searched", function (req, res) {
      if (req.isAuthenticated()) {
        const { page } = req.query;
    
        const options = {
          sort: { dateAdded: -1 },
          page: !page ? 1 : page,
          limit: 20,
        };
    
        const query = req.query;
    
        delete query.page;
    
        if (query.btu === "") {
          delete query.btu;
        }
    
        if (query.sn1 === "") {
          delete query.sn1;
        }
    
        if (query.sn2 === "") {
          delete query.sn2;
        }
    
        if (query.userCreated === "") {
          delete query.userCreated;
        }
    
        if (query.split === "") {
          delete query.split;
        }
    
        if (query.supplier === "") {
          delete query.supplier;
        }
    
        if (query.issued === "") {
          delete query.issued;
        }
    
        var queryString = objectToQueryString(query);
    
        console.log(queryString);
        Aircon.paginate(query, options, function (err, results) {
          if (err) {
            console.log(err);
          } else {
            res.render("instock", {
              foundAircons: results.docs,
              total: results.totalDocs,
              hasPrev: results.hasPrevPage,
              hasNext: results.hasNextPage,
              pageCount: results.totalPages,
              page: results.page,
              url: queryString,
            });
          }
        });
      } else {
        res.redirect("/login");
      }
    });

Related Articles