Client side Pagination through Custom Angular JS Filter

Angular JS is a powerful front-end framework and often I have tried and successfully delegated it responsibilities for which I might have written a good chunk of code on the server back-end. One such instance was pagination. If you are not familiar, pagination is a technique through which we present tabular data to the user by breaking it into pages.

In one of my projects, I encountered a use-case in which the size of the records coming in was not very very huge. I wanted to paginate the records to enhance the user experience and making round trips to the server to fetch each page felt like forever. It is then I decided to completely handover my pagination responsibilities to the front-end.

I could have done everything I needed to paginate the records on the controller with Loadash doing all the heavy lifting and filtering for me, but I felt guilty. It felt like treason to write something that “un-re-useable”. Beautiful software is not complex, it is simple.  So, I wanted to create a custom filter in Angular JS which would filter out the records for me and all I needed to do was to give it suitable parameters through my view. And then I can use the “all-famous” UI-Bootstrap controls for pagination to show the user what page are you on, how many pages are there altogether etc.

The bird’s eye view of the filter function was:

Input: 1) Complete list of records, 2) Requested page number (we will call this current page) and 3) Records per page

Output: List of records for the requested page

Here is how simple and tiny the filter came out to be …

Its usage is even simpler.

Hook it up as a filter to the ng-repeat expression as follows and it would to all the pagination stuff for you.

— Look for hints in the comments

Pretty simple huh ?

Its complete source can be found in this little github repository. Just clone the it and open up “index.html” and browse to the pagination demo.

It’s good, isn’t it ? — Big Boss

Advertisements

Javascript Testing – Clean object mocking through JSON files

Clean code is what is over my head for the past few days. Thanks to an excellent course by John Papa, Angular JS Patterns: Clean Code on Pluralsight, it has made think why there is a constant need to improve in the way we write code. One thing that struck my mind is the separation of concern, which is essential not only in understanding the code, but also in maintaining the code over long periods of time. I am a big fan of testing my javascript ( … you should be too) and previously I have made an attempt to write clean tests to make them readable, scaleable and all that magic. The motivation behind writing that was a line we hear usually once every sprint, “Hey, lets add this …. “. My previous post outlines one approach but this time I have decided to take it one level up.

So, I will be using an overly simplistic Angular JS controller as a “proof of concept” to demonstrate how we can make our tests cleaner. Have a look at this controller, it contains a call to a service, through which it receives data and upon resolution of the promise, it attaches it to the view via the “vm” variable.

Note: I am using the “Controller As” syntax so bye bye $scope and hello cleanliness.

To test this controller I needed to mock the call to the “dataservice” which returns a mocked response. There are 3 ways we can mock the response.

The Good: because it works!

Declare the mock object in the test file as a javascript variable. This approach is common but it makes the test file feel like spaghetti. Its hard to find stuff and you need to copy over the mock objects if they are used in more than one file. Yuck !

The Better: because we are getting there …

Declare the mock object in a mock Angular JS factory and expose it via a return object. This approach was blogged earlier here. The problem with this approach is that the mock Angular JS factory gets messier as the objects are added to it. It becomes one long/big file making it harder to maintain. Okay …. 

The Best: Bingo!

Declare the mock object in a JSON file, load it inside an Angular JS factory and expose it via a return object. I find this approach to be the best. Each object has its own file and is cleanly loaded into the Angular JS mock factory. The separation of objects into their own files make it a ton easier to maintain. That’s more like it ! 

In order to achieve the “Best” way to mock objects, we will make use of “jQuery-Jasmine” through which we will load the objects form the JSON file but it requires little bit of configuration so lets go through it step by step:

1. Install jquery-jasmine as a development dependency via npm

Run “npm install jquery-jasmine –save-dev” on the root of your project via terminal/bash/cmd.

2. Include jquery, jquery-jasmine as “files to be loaded”

Since I am using Karma to run my Jasmine tests, I only need a simple addition to the files array in my karma.conf.js file. See image below step 3.

3. Include the JSON files as “files to be loaded”

Similar to the previous step, add the JSON files to the files array in the karma.conf.js.

karma.conf.js

karma.conf.js

4. Let Jasmine know from where to load the JSON files from

I have a separate Angular JS module for my mocks, so the place where I declare my module is the place I use to declare the relative path of my tests which would be loaded on the browser.

Note: This path is something karma makes when it loads the tests from the file system onto the browser and can change in the upcoming releases.

 

Screen Shot 2014-11-10 at 12.06.06 am

This is it for the configuration, now we need to create an Angular JS factory which would load the JSON files and expose them as objects in our test files. Here is the JSON file and how we load it into our mock Angular JS factory …

And finally…. This is how the tests look like.

I must say, transitioning from good to better to best feels a lot satisfactory.

All of you can now safely get up from your chairs and do this ….