Sunday 7 April 2013

How to Parse Nested XML using Sencha Touch 2 - Part2

This Post is the continuation of where we left in Part1, If you haven't read, Please read first and continue reading this Post.

Define a Store

Now, Let's define a Store with Class name 'IssueStores' and storeId configuration as 'issuestores'. This Store will load the 'data.Issue.xml' file (defined in part1) configured in url config using Ajax Proxy config. This Ajax Proxy configuration also contains reader config which will read Nested XML using the rootProperty and record property configuration.

Ext.define('MyApp.store.IssueStores', {
    extend: 'Ext.data.Store',
    alias: 'store.issuestores',

    requires: [
        'MyApp.model.Issue'
    ],

    config: {
        autoLoad: true,
        model: 'MyApp.model.Issue',
        storeId: 'issuestores',
        proxy: {
            type: 'ajax',
            url: 'data/Issue.xml',
            reader: {
                type: 'xml',
                rootProperty: 'Issue',
                record: 'Issue'
            }
        }
    }
});

Parse the Nested XML

Now, let's see the main application logic, read the nested XML using above registered store ('issuestores') and display the articles headlines with sections as console log output.

Ext.application({
    models: [
        'Issue',
        'Article',
        'Section1'
    ],
    stores: [
        'IssueStores'
    ],
    name: 'MyApp',

    launch: function() {
        var issueStores = Ext.getStore('issuestores');
        issueStores.load(function(records, options, success){

            //console.log(records);
            if(success){
                Ext.each(records,function(record){
                    console.log('Issue Name: '+record.data.Name);
                    var sections = record.section();

                    if(sections.data.length > 0){
                        //console.log(sections.data.items);
                        Ext.each(sections.data.items,function(section){

                            console.log('Section: '+section.data.SectionName);
                            var articles = section.articles();
                            if(articles.data.length > 0){

                                Ext.each(articles.data.items,function(article){
                                    console.log('Article ID: '+article.data.ArticleId+ ' Article HeadLine: '+article.data.ArticleHeadline);
                                });
                            }
                        });
                    }
 
                });
            }
        });
    }

Explanation:

First, Let's access the registered store using getStore() function with 'StoreId' property. Store load() callback function is triggered for every issue record in the store. Using 'name' Property in hasMany Association  defined on Issue Model Class (Part1 of this Post) as a function section(), we are going to access array of section records associated for this Issue.

Then, using Ext.each() we are going to loop each section records and trying to access array of article records associated for each section record using 'name' Property in hasMany Association  defined in Section Model Class (Part1 of this Post) as a function articles() and display the record details in browser console using console.log().

When i run this code in Google Chrome, Following is the console log output



Hope, you enjoyed this Post.

12 comments:

  1. Hi suresh, first of all, thanks for your tutorial, is excelent.

    I'm following your tutorial with my own implementation but when I try to access to subelements of the main element i get this error:

    [Object Object] has no method 'languages'

    I posted a question in stackoverflow http://stackoverflow.com/q/15896921/2248121

    ReplyDelete
    Replies
    1. Thanks for your appreciation.
      In 'Language' model class (Eugin.Model.Language), proxy configuration type (memory) and reader configurations (rootpropery and record) are missing. Something like below

      proxy: {
      type: 'memory',
      reader: {
      type: 'xml',
      rootProperty: 'eugin-language',
      record: 'eugin-language'
      }
      }


      Delete
    2. Thanks suresh for your quick answer.

      I added your piece of code to subelement model, but i get the same result.

      I seems that sencha doesn't generate the method "languages" of the hasMany elements.

      Any other ideas?

      Delete
    3. In Tip Model Class (Eugin.model.Tip), You need to add the below line

      associationKey: 'eugin-language'

      Inside 'hasMany' Association config property. Something like this

      hasMany: {
      associationKey: 'eugin-language',
      model: 'Eugin.model.Language',
      name: 'languages'
      }

      Delete
    4. Thanks, but it doesn't work :(

      Delete
    5. I tried your code from my side (by taking from stackoverflow) and it works perfect. I attached the code here

      http://www.ziddu.com/download/21978383/test.zip.html

      Hope, this helps.

      Delete
    6. Thank you very much Suresh!!! :)

      I think that the problem is that I don't put the model files into de model folder and i don't defined in the app.js file.

      Sorry for your waste of time but I'm a newbie with sencha.

      I apreciate your dedication.

      Delete
    7. Thanks you so much for your kind words.

      Delete
  2. Hi Suresh,

    Your example here is great. I've been using your tutorial here but even in a simpler example and can't get it to work. Would you have 10 seconds to look at my issue posted here:

    http://www.sencha.com/forum/showthread.php?262694-Nested-XML-using-hasMany-is-not-working-for-me&p=962678

    I don't get what I'm doing wrong!

    ReplyDelete
    Replies
    1. In GroupsWithMemebers Model class, you need to add 'uses' configuration points to member model class.

      In Member Model Class, you need to add memory Proxy Configuration. Something like this

      proxy: {
      type: 'memory',
      reader: {
      type: 'xml',
      rootProperty: 'Articles',
      record: 'Article'
      }
      }

      Thanks

      Delete
  3. great work suresh!

    ReplyDelete