meanpag

0.0.7 • Public • Published

MEANPag (Mongooose Express Ajax Node Pagination)

Client pagination of mongoDb using AJAX? MEANPag to the rescue!

Description

  • MEANPag is the JS AJAX pagination library for the MongoDB (and Mongoose) that works on a client.
  • I use browserify library to package it so you can easily use it on both client and Node server with require().
  • On the client we add dist/paginator.js and use new window.MEANPag() to obtain paginator.
    • The client issues an AJAX request to the NodeJS server
      • AJAX request has the "filter" parameter set from paginator.getFilter()
    • Server (Node + Express) obtains the pagination parameters from request (ex. req.body.filter param) and sets the new paginator with it:
      • new Paginator().setFilter(req.body.filter)
      • after that we return necessary records from a database using two queries: a. get count of # of records b. get the records

Small example

Client

var paginator = new window.MEANPag();
paginator.and({name: "Bob"});
//...issue new XMLHttpRequest with data: { filter: paginator.getFilter() }

Server

router.post("/users", setupPaginationFilter, getUsers, function (req, res, next) {
    return res.json({
        filter: res.locals.paginator.getFilter(),
        users : res.locals.users
    });
});

for the setupPaginationFilter, getUsers see below

Components

  • Paginator - object that holds data relevant to paging. Contains/builds an instance of QueryBuilder

    • Public API consists of QueryBuilder's API together with the following:
      • QueryBuilder: "getQueryBuilder"
      • total items: "setTotal", "setTotalItems", "getTotal", "getTotalItems"
      • total pages: "setTotalPages", "getTotalPages"
      • page: "setPage", "getPage"
      • skip: "getSkip"
    • On the server:
      • "filterMongooseCollection([mongooseObject, errorCb, successCb])"
      • "getFilter"
  • QueryBuilder - a core object that builds the mongoose query and provides mongoose methods

    • QueryBuilder's Public API consists of the following methods:
      • Comparison/Logical operators: *"gt", "gte", "lt", "lte", "ne", "in", "nin", "regex"
      • Object getters/setters:
        • Filter (find + sort + limit) param : "getFilter", "setFilter", "filter", "clearFilter"
        • Find param: "getFind", "setFind", "find", "findWhere", "setFindFieldExpression", "getAreEmptyFindExpressions", "clearFind"
        • Sort param: "getSort", "setSort", "sort", "sortAsc", "sortDesc", "clearSort"
        • Limit param: "getLimit", "setLimit", "limit", "noLimit", "clearLimit"
  • Server example of querying "Users":

      // AJAX (POST) to /users
      router.post("/users", setupPaginationFilter, getUsers, function (req, res, next) {
          // your data output (like res.json({}))
          return sendSuccessResponse({
              filter: res.locals.paginator.getFilter(),
              users : res.locals.users
          }, res, next);
      });
        
      // setting the paginator
      function setupPaginationFilter (req, res, next) {
          res.locals.paginator = new Paginator().setFilter(req.body.filter);
          return next();
      }
      
      // obtaining results
      function getUsers (req, res, next) {
        
          res.locals.paginator.filterMongooseCollection(
              Users,
              function errorCallback (err) {
                  // do something with errors...
                  return sendErrorResponse(err, res, next);
              },
              function successCallback (data) {
                res.locals.users = data;
                return next();
              }
          );
      }
    
  • Client example of issuing AJAX request with paginator

<script type='text/javascript' src='bundle.js'></script>
<script>

$(document).ready(function () {

    var paginator = new window.MEANPag(),
        zip = "11230";
    
    paginator.findWhere({
        // Find all users by zipCode regEx (in user's address sub-document)
        "address.zipCode": QueryBuilder.regex((zip).toString(), "i")
    });

    $.ajax({
        method: 'POST',
        url : '/users',
        data: { filter: paginator.getFilter() },
        success: function (data) {
            if (data.success == true) {
                // returns data.filter + data.users, do something with it
                console.log(data.users, data.filter);
                // reset the paginator's filter with new data from the server,
                // clear the find (zip) so it does not stack.
                paginator.setFilter(data.filter).clearFind();
            }
        },
        dataType: 'json'
    }); 
});
</script>

Demo

To see MEANPag demo, come here

Security

From what I can tell sql injection is not a problem with MongoDB because of the way it works with data by building it into a BSON-format object instead of parsing/building a string as in SQL. On MongoDB SQL Injection. However you have to look at what collections you are allowing users to query. In the demo example I query the users collection, but of course in production environment such querying should be avoided. If you have to add something, please free to open up an issue.

/meanpag/

    Package Sidebar

    Install

    npm i meanpag

    Weekly Downloads

    1

    Version

    0.0.7

    License

    MIT

    Last publish

    Collaborators

    • gogromat