PDA

View Full Version : JSONP + XML (JSONPX) Reader



tinyfactory
2 Aug 2012, 4:02 PM
I was integrating with a client's API which used a blend of JSONP and XML. Sencha Touch 2 does not have a native way to parse this, so I extended XML reader to make a 'jsonpx' reader. Hopefully this will help someone who might run into the same situation.



Ext.define('app.util.JsonpX', {
extend: 'Ext.data.reader.Xml',


// Set the proxy alias
alias: 'reader.jsonpx',


parseXmlString: function (sXml) {
// If the specified XML document content is a string...
if (typeof sXml == "string") {


// Create a reference to the XML document parser.
var oParser = new DOMParser();


// Return the reference to the XML document.
return oParser.parseFromString(sXml, "text/xml");
}
else { // XML document content is NOT a string...
// Return the specified XML document since it has already been parsed.
return sXml;
}
},


/*
* override
* @param {string} response the response to parse
* @return {xml} the XML data that has been parsed
*/
getResponseData: function(response){
response = this.parseXmlString(response);
return response;
}
});


To use, place the above code in a file [app root]/util/jsonpX.js

Inside of the store you are using, make sure to include and declare it as the reader. For example:



Ext.define('Year', {
extend: 'Ext.data.Model',
config: {
fields: [
{name: 'id', type: 'number'}
]
}
});


Ext.define('smtp.store.PartsFilterYear', {
extend: 'Ext.data.Store',
requires: [
'Ext.data.proxy.JsonP',
'app.util.JsonpX'
],
config: {
autoLoad: true,
storeId: 'PartsFilterYear', // ref to bind inside views
model: 'Year',
fields: ['id'],
pageSize: 100,
proxy: {
type: 'jsonp',
url: 'http://somedomain.com/someapi',
reader: {
type: 'jsonpx' //declare reader
}
}
}
});


This code was inspired by a piece a found for Sencha Touch 1 - http://www.sencha.com/forum/showthread.php?12852-ScriptTagProxy-and-XML

Hope this helps.

mitchellsimoens
4 Aug 2012, 7:29 PM
Nice.

galdaka
15 Sep 2012, 7:31 AM
With this code you can use JsonP proxy for read XML?

I test it, but not work.

Thanks.

tinyfactory
16 Sep 2012, 10:36 AM
Yes, but there are 2 conditions to make this work:
The API accepts JSONP like callbacks i.e. http://www.domain.com/someapi?callback=foo will return:
foo('...data...');
The API returns the XML as a string (i.e. '<person><name>Alex Rolek</name></person>').
For an example of what your response should look like, here is the API I interfaced with:
http://www.showmetheparts.com/bin/mShowMeWebXML.exe?lookup=year&_dc=1347820493871&page=1&start=0&limit=100&callback=Ext.data.JsonP.callback1

This reader will make the JSONP request, then parse the XML string into XML.

If you are having problems, feel free to post some code, and/or the API you are pinging and I will take a look at it.

kjlee203
14 Oct 2012, 7:36 AM
I try url?http://www.domainB.com/cms/rss/index.xml,but i get the errors:
"Resource interpreted as Script but transferred with MIME type text/xml......,Uncaught SyntaxError: Unexpected token < "
can you help me ?thanks.

eam2nd
15 Mar 2013, 6:52 AM
I'm trying to implement your jsonpX script using the same API (url) you gave and I am receiving the error in the title of this message. I have Year as a model and PartsFilterYear as a store and as of now, I'm not doing anything with it, but, since autoload = true, it's trying to load the model from the store and I receive this error.

Ext.define('JsonPx.model.Year', {
extend: 'Ext.data.Model',

config: {
fields: [
{name: 'id', type: 'number'}
]
}

});

Ext.define('JsonPx.store.PartsFilterYear', {
extend: 'Ext.data.Store',

requires: [
'Ext.data.proxy.JsonP',
'JsonPx.util.jsonpX'
],

config: {
autoLoad: true,
storeId: 'PartsFilterYear', // ref to bind inside views
model: 'JsonPx.model.Year',
fields: ['id'],
pageSize: 100000000,
proxy: {
type: 'jsonp',
url: 'http://www.showmetheparts.com/bin/mShowMeWebXML.exe?lookup=year&_dc=1347820493871&page=1&start=0&limit=100&callback=Ext.data.JsonP.callback1',
reader: {
type: 'jsonpx' //declare reader
}
}
}
});

In my app.js I am, obviously, referencing the Year as a model and PartsFilterYear as a store. When I open the url in a browser all seems fine.

When I click the error link in the Safari console, it shows this:
Ext.data.JsonP.callback1
Ext.data.JsonP.callback1('

What am I doing wrong?
Thanks.