in Appcelerator Titanium

Paging Through a Large Result Set with Titanium and Appcelerator Cloud Services

Titanium 2.0 was released today, and a big feature is Appcelerator’s new Cloud Services (formerly Cocoafish).  I have been beta testing the past few weeks, and I’m getting pretty excited about the release and new features!

One thing I ran into while working on an integration into a client’s app is that we will want to be able to update some records (or documents, since we are talking mongo-type stuff) that are kept locally on the app.  There should only be a few new/changed records to be downloaded on an irregular basis, but for the first update, everything is new, so there will be hundreds of records to download.

This is fine, except it currently looks like ACS limits queries to 100 results, with a default of 10.  So much for downloading everything at once.  Aww, man!  Actually, it is pretty common for APIs to have this type of setup, called paging or pagination, including APIs that have a per request pricing structure — good way to squeeze some extra calls out of you 🙂  There is a lot of discussion on pros and cons of paging out there, so we won’t get into it here.

Fortunately, it is pretty easy to handle paging through multiple queries.   In addition to regular search parameters, Ti.Cloud queries also accept optional parameters:

  • per_page: maximum number of results to retern per result set, or page (max 100)
  • page: which page to return with the query

It is also worth noting that pages start at 1, and default to 1.

So, with those two parameters we can set up a function make as many queries as needed to get all the pages for our query results.

Additionally, we will need to how many pages total are in our query results, so we know how many to make.  Each query to Ti.Cloud returns some additional info under ‘meta’, including meta.total_pages, which we can use to find the max number of times to make the query.

Example

Here is a simple gist for paging through and querying custom objects per page. I am making use of the example in the Titanium 2.0 custom object documentation.

//paging through large query result sets with Titanium and ACS
//http://adampaxton.com
 
function doQuery(n){
    Cloud.Objects.query({
       classname: 'cars',
       per_page: 100,
       page: n || 1
    }, function (e) {
        if (e.success) {
            Ti.API.info('Result set length : ' + e.cars.length);
            for (var i = 0; i < e.cars.length; i++) {
                var car = e.cars[i];
                Ti.API.info('id: ' + cars.id + '\\n' +
                    'make: ' + car.make + '\\n' +
                    'color: ' + car.color + '\\n' +
                    'year: ' + car.year + '\\n' +
                    'created_at: ' + car.created_at);
            }
        if(n < e.meta.total_pages){
            doQuery(++page);
        }
        } else {
            alert('Error:\\n' +
                ((e.error && e.message) || JSON.stringify(e)));
        }
    });
}
 
var page = 1;
doQuery(page);
Of course, you’ll always want to be conscious of your users potentially having to retrieve this data over their phone’s data connection, which may charge, have limits, etc., so it is always a good idea to work to only transfer the minimal amount of data possible.

About

Adam is a TCAD and ATMD certified Titanium developer.  Contact him here for Titanium development and consulting for your next app.