Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nested XML data and ExtJS model associations

I'm trying to map XML data to a series of models in ExtJS. I'm able to extract the data from the toplevel model, however, the associations with it fail to retrieve the necessary data.

Here are all of my models:

Ext.define('app.model.ProductType', {
    extend: 'Ext.data.Model',
    idProperty: 'id',
    fields: [{
        name: 'id',
        mapping: 'id',
        type: 'int'
    }, {
        name: 'name',
        mapping: 'name',
        type: 'string'
    }, {
        name: 'sometag',
        mapping: 'sometag',
        type: 'string'
    }],
    associations: [{
        type: 'hasMany',
        model: 'app.model.Address',
        name: 'addresses',
        autoLoad: true,
        reader: {
            type: 'xml',
            record: 'address',
            root: 'addressList'
        }
    }, {
        type: 'hasMany',
        model: 'app.model.PhoneContact',
        name: 'contacts',
        autoLoad: true,
        reader: {
            type: 'xml',
            record: 'phoneContact',
            root: 'phoneContactList'
        }
    }, {
        type: 'hasOne',
        model: 'app.model.OneToOne',
        name: 'oneToOne',
        autoLoad: true,
        reader: {
            type: 'xml',
            record: 'oneToOne'
        }
    }],
    proxy: {
        type: 'ajax',
        url: 'data/example.xml',
        reader: {
            type: 'xml',
            record: 'ProductType',
            root: 'ProductResultSet'
        }
    }
});

Address:

Ext.define('app.model.Address', {
    extend: 'Ext.data.Model',
    fields: [{
        name: 'city',
        mapping: 'city',
        type: 'string'
    }, {
        name: 'street',
        mapping: 'street',
        type: 'string'
    }],
    associations: [{
        type: 'belongsTo',
        model: 'app.model.ProductType'
    }]
});

PhoneContact:

Ext.define('app.model.PhoneContact', {
    extend: 'Ext.data.Model',
    fields: [{
        name: 'primary',
        mapping: 'primary',
        type: 'string'
    }, {
        name: 'cell',
        mapping: 'cell',
        type: 'string'
    }],
    associations: [{
        type: 'belongsTo',
        model: 'app.model.ProductType'
    }]
});

OneToOne:

Ext.define('app.model.OneToOne', {
    extend: 'Ext.data.Model',
    fields: [{
        name: 'first',
        mapping: 'firstfield',
        type: 'string'
    }, {
        name: 'second',
        mapping: 'secondfield',
        type: 'string'
    }],
    associations: [{
        type: 'belongsTo',
        model: 'app.model.ProductType'
    }]
});

Here's my app.js

Ext.Loader.setConfig({
    enabled: true
});

Ext.application({
    name: 'app',
    autoCreateViewport: false,
    requires: ['app.model.ProductType', 'app.model.Address', 'app.model.PhoneContact', 'app.model.OneToOne', 'app.store.ProductTypeStore'],
    launch: function () {
        app.model.ProductType.load(55, {
            scope: this,
            callback: function (record, operation) {
                console.log('Record Addresses:');
                console.log(record.addresses());
            }
        });

        var s = app.store.ProductTypeStore.create();
        s.on('load', this.wiggidy, this);
        s.load();
    },
    wiggidy: function (store, records, success, eOpts) {
        var rec = store.getAt(0);
        console.log('Associated Data:');
        console.log(rec.getAssociatedData());
    }
});

And finally, example.xml

<ProductResultSet>
<ProductType>
    <id>55</id>
    <name>Product Name</name>
    <sometag>asdf</sometag>
    <addressList>
        <address>
            <street>12345 a</street>
            <city>myCity</city>
        </address>
        <address>
            <street>234567 b</street>
            <city>Denver</city>
        </address>
    </addressList>
    <phoneContactList>
        <phoneContact>
            <primary>234</primary>
            <cell>4667</cell>
        </phoneContact>
        <phoneContact>
            <primary>5467</primary>
            <cell>87904</cell>
        </phoneContact>
    </phoneContactList>
    <oneToOne>
        <firstField>value</firstField>
        <secondField>value</secondField>
    </oneToOne>
</ProductType>
</ProductResultSet>

The console spits out "Uncaught TypeError: Cannot call method 'indexOf' of undefined" for the RecordAddresses output, and then I get an object filled with arrays with 0 objects for the Associated Data output.

I'm completely stumped on this one. I've searched around everywhere and it's taken me this far. Why is the record not loading the nested data in that xml file?

Any help will be greatly appreciated.

like image 820
guitarist809 Avatar asked Feb 15 '26 02:02

guitarist809


1 Answers

Why are you setting autoLoad=true in the hasMany relationship?

You are trying to use nested data, and then you are telling it to load the data on demand, and wondering why there is no nested data :)

You are also missing the associationKey, which is required for nested loading.

Here is a working example of your code:

http://jsfiddle.net/el_chief/668Fg/5/

Follow my "Rules" in the future and everything will be ok:

http://extjs-tutorials.blogspot.ca/2012/05/extjs-hasmany-relationships-rules.html

like image 101
Neil McGuigan Avatar answered Feb 16 '26 16:02

Neil McGuigan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!