1. #1
    Touch Premium Member
    Join Date
    Feb 2011
    Location
    San Diego, CA
    Posts
    43
    Vote Rating
    4
    tinyfactory is on a distinguished road

      0  

    Default JSONP + XML (JSONPX) Reader

    JSONP + XML (JSONPX) Reader


    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.

    Code:
    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:

    Code:
    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/showthre...gProxy-and-XML

    Hope this helps.

  2. #2
    Sencha - Senior Forum Manager mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    37,642
    Vote Rating
    898
    mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute

      0  

    Default


    Nice.
    Mitchell Simoens @SenchaMitch
    Sencha Inc, Senior Forum Manager
    ________________
    Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
    https://github.com/mitchellsimoens

    Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/

    Need more help with your app? Hire Sencha Services services@sencha.com

    Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is in print!

    When posting code, please use BBCode's CODE tags.

  3. #3

  4. #4
    Touch Premium Member
    Join Date
    Feb 2011
    Location
    San Diego, CA
    Posts
    43
    Vote Rating
    4
    tinyfactory is on a distinguished road

      0  

    Default


    Yes, but there are 2 conditions to make this work:
    1. The API accepts JSONP like callbacks i.e. http://www.domain.com/someapi?callback=foo will return:
      Code:
      foo('...data...');
    2. 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/mS...sonP.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.

  5. #5
    Sencha User
    Join Date
    Mar 2008
    Posts
    9
    Vote Rating
    0
    kjlee203 is on a distinguished road

      0  

    Default url:‘http://www.domainB.com/cms/rss/index.xml’,it doesn't work.

    url:‘http://www.domainB.com/cms/rss/index.xml’,it doesn't work.


    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.

  6. #6
    Sencha User
    Join Date
    Mar 2013
    Posts
    1
    Vote Rating
    0
    eam2nd is on a distinguished road

      0  

    Default SyntaxError: Unexpected EOF mShowMeWebXML.exe:2

    SyntaxError: Unexpected EOF mShowMeWebXML.exe:2


    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.