Sencha touch : Ajax, Jsonp and scripttags

2011, Oct 24    

I started using the Sencha Touch javascript framework a number of weeks ago.  The basic plan for the application was to create a fully functioning web app, then using phonegap create a native iOS application.

The problem with this approach was that i ended up using Ext.Ajax.request to do all of the data calls without worrying about how phonegap would deal with ajax and the json objects that it was returning.  Needless to say the app didn’t work.  Any calls for data that go outside of the ipad are cross domain calls and need to be implemented with script and jsonp.

 Standard Ajax/Json request

function GetReportChartAjax() {
  Ext.Ajax.request({
    url: this.reportUrl,
    timeout: 180000,
    disableCaching: true,
    success: function (response, opts) {
      this.GetReportChartCallback(response);
    },
    failure: function (response, opts) {
      this.reportCarousel.setLoading(false);
      console.warn(response);
    }
  });
}

 

JSONP Request

function GetReportChartJsonp() {
  //Start a timer to handle the JSNOP request timing out.
this.jsonpTimeoutTimerId = window.setTimeout("JsonPRequestTimeoutCheck()", 30000); // for 30 sec

   var jp = Ext.util.JSONP.request({
     url: this.reportUrl,
     callbackKey: 'jsoncallback',
      scope: this,
    callback: this.GetReportChartCallback
    });
  }
function JsonPRequestTimeoutCheck() {
  Ext.util.JSONP.callback({ 'Success': false, 'Errors': ['Timed out'] });
}

 

Asynchronous JSONP : The Problem

Now the problem with using the JSONP class is that it’s a singleton.  So by moving from
Ext.Ajax.request to Ext.util.JSONP.request we’ve not only lost the timeout capability, we’re also lost the ability to make asynchronous calls.

If you google it, you’ll find that one suggested approach is to set current to null before each jsonp request. It’s certainly been my experience from using Sencha 1.1 that this doesn’t work.

 

//Doesn't work
//Ext.util.JSONP.current = null;

 

Asynchronous JSONP : The Solution

The solution is to use a store with a scripttag proxy. As all that’s actually happening is a scripttag being rendered to the page making the request, then you’ll be allowed as many calls as your browser can handle.

We then specify a callback parameter on the load method which allows us to interact with the actual response object rather than let the store fiddle with this json in preparation for it being wrapped up inside a data view.

 

function GetReportChartJsonpProxy() {

    var repStore = new Ext.data.Store({
      model: 'ReportImageResponse',
      proxy: {
        type: 'scripttag',
        url: this.reportUrl,
        reader: {
          type: 'json'
        },
        callbackPrefix: 'ReportCallback',
        timeout: 30000
      }
    });

    repStore.load({
      scope: this,
      callback: function (records, operation, success) {
        this.GetReportChartCallback(operation.response);
      }
    });

  }