0

It seems to be very basic question, but happens to kill lot of my time.

How can I map following in to Ext.data.Model?

<Principal>STEMMED CORP.</Principal>
<BusinessDefinitions>
    <value>NY CLIENTS CORE</value>
    <value>US LISTED DERIVS- STOCK,ADR,ETF</value>
    <value>US CLIENT SITE TRADING</value>
    <value>SYNDICATES - ADRS AND CBS</value>
    <value>GWM CAPITAL MARKETS</value>
</BusinessDefinitions>
<countryOfResidence>USA</countryOfResidence>

Problem is, I unable to figure out how to get array of string for BusinessDefinitions against each value.

The following field is what I have added to Model.fields:

// Business Definition(s)
{
    name: 'BusinessDefinitions',
    type: 'auto',
    mapping: 'value',
    convert: function(n, record) {
        console.log('BusinessDefinition: ' + n);
        return n;
    }                       
} 

I have tried other combinations as well, but nothing seem to work.

3
  • Have you tried using JSON instead of XML as your data provider? Commented Mar 4, 2015 at 16:04
  • Wish I could.! But, I am supporting older service which only outputs XML Commented Mar 4, 2015 at 16:12
  • What I need is, model should contain property named 'BusinessDefinitions' of type array(of string). here array contains each 'value' as string Commented Mar 4, 2015 at 16:32

2 Answers 2

3

The following was fabricated to fit your data from the example below.

Here is a Sencha Fiddle of the answer I have provided. It is 4.2.1.883 compliant. I have yet to try this with version 5.1.0.

Data

<BusinessArray>
    <BusinessItem>
        <Principal>STEMMED CORP.</Principal>
        <BusinessDefinitions>
            <value>NY CLIENTS CORE</value>
            <value>US LISTED DERIVS- STOCK,ADR,ETF</value>
            <value>US CLIENT SITE TRADING</value>
            <value>SYNDICATES - ADRS AND CBS</value>
            <value>GWM CAPITAL MARKETS</value>
        </BusinessDefinitions>
        <countryOfResidence>USA</countryOfResidence>
    </BusinessItem>
</BusinessArray>

Application

Ext.define('App.model.Business', {
    requires: [ 'Ext.data.reader.Xml' ],
    extend: 'Ext.data.Model',
    fields: [{
        name: 'principal',
        mapping: 'Principal',
        type: 'string'
    }, {
        name: 'country',
        mapping: 'countryOfResidence',
        type: 'string'
    }, {
        name: 'businessDefs',
        type : 'auto',
        convert: function(value, record) {
            var nodes = record.raw.querySelectorAll('BusinessDefinitions value');
            var items = [];
            for (var i = 0; i < nodes.length; i++) {
                items.push(nodes[i].textContent);
            }
            return items;
        }
    }] 
});
Ext.application({
    name : 'Fiddle',
    launch : function() {
        var store = Ext.create('Ext.data.Store', {
            model: 'App.model.Business',
            proxy: {
                type: 'ajax',
                url: 'business.xml',
                reader: {
                    type: 'xml',
                    record: 'BusinessItem'
                }
            },
            autoLoad : true
        });
        Ext.create('Ext.panel.Panel', {
            title : 'XML Model Example',
            layout : 'hbox',
            items : [{
                xtype: 'combo',
                fieldLabel: 'Business',
                emptyText: 'select',
                editable: false,
                queryMode: 'local',
                store: store,
                displayField: 'principal',
                valueField: 'businessDefs',
                listeners : {
                    select: function (combo, record, index) {
                        Ext.Msg.alert('Business Definitions', combo.getValue().join('<br />'));
                    }
                }
            }],
            renderTo: Ext.getBody()
        });
    }
});

Example

The example below is from the accepted solution from Sencha Forums: How do I parse a XML node to an array of strings? Also handing XML attributes?.

XML Data

<jobs>
    <job>
        <id>1</id>
        <name audioSrc="audio/jobs/names/electrician.mp3">Electrician</name>
        <attributes>
            <attributeID>sitting</attributeID>
            <attributeID>individual</attributeID>
            <attributeID>lightEquip</attributeID>
            <attributeID>doer</attributeID>
            <attributeID>physical</attributeID>
            <attributeID>repair</attributeID>
        </attributes>
    </job>
</jobs>

Store

Ext.create('Ext.data.Store', {
    model: 'App.model.JobData',
    proxy: {
        type: 'ajax',
        url: dataURL,
        reader: {
            type: 'xml',
            record: 'job'
        }
    }        
});

Model

Ext.define('App.model.JobData', {
    requires: [ 'Ext.data.reader.Xml' ],
    extend: 'Ext.data.Model',
    config: {
        fields: [{
            name: 'id',
            mapping: 'id',
            type: 'int'
        }, {
            name: 'title',
            mapping: 'name',
            type: 'string'
        }, {
            name: 'attributeList',
            mapping : 'attributes',
            convert: function(value, record) {
                var nodes = record.raw.querySelectorAll('attributes attributeID');
                var arrayItem = [];
                var l = nodes.length;
                for (var i = 0; i < l; i++) {
                    var node = nodes[i];
                    arrayItem.push(nodes[i].textContent);
                    console.log(nodes[i].textContent);
                }
                return arrayItem;
            }
        }] 
    }
});
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for your detailed answer.! Got proper direction with it.
0

Following is what worked for me: No need to add requires: [ 'Ext.data.reader.Xml' ], With that, following is the final field

},{
            //Business Definition/s
            name: 'BusinessDefinitions',
            type: 'auto',
            mapping: function(data){
                return data.children[2].children[10];
            },          
            convert: function(value, record) {
                var items = [];
                var nodes = record.data.BusinessDefinitions.querySelectorAll('BusinessDefinitions value');

                for (var i = 0; i < nodes.length; i++) {
                    items.push(nodes[i].textContent);
                }
                return items;
            }                   
        },   

1 Comment

Yeah, the requires was just an oversight. It was modeled after the example at the end of my post. It is harmless and just serves as a reminder that this model is to be paired with an XML reader since it is modeling XML data coming in.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.