stormdrain
stormdrain

Reputation: 7895

extjs parsing nested json in template

Trying (unsuccessfully) to display data from nested json.

JSON might look something like:

{
    "contacts": [
        {
            "id": "1",
            "client_id": "135468714603",
            "addresses": [
                {
                    "id": "1",
                    "contact_id": "1",
                    "address_id": "16",
                    "address": {
                        "0": {
                            "id": "16",
                            "address": "123 Some Rd",
                            "address2": "",
                            "city": "Toen",
                            "state": "VS",
                            "zip_code": "11111",
                            "country": "USA"
                        }
                    }
                },
                {
                    "id": "6",
                    "contact_id": "1",
                    "address_id": "26",
                    "address": {
                        "0": {
                            "id": "26",
                            "address": "1 Other Road",
                            "address2": "",
                            "city": "Twn",
                            "state": "BD",
                            "zip_code": "11112",
                            "country": "USA"
                        }
                    }
                }
            ]
        },
        {
            "id": "10",
            "client_id": null,
            "addresses": [
                {
                    "id": "8",
                    "contact_id": "10",
                    "address_id": "28",
                    "address": {
                        "0": {
                            "id": "28",
                            "address": "54 Road",
                            "address2": "",
                            "city": "TWND",
                            "state": "TT",
                            "zip_code": "11113",
                            "country": "USA"
                        }
                    }
                },
                {
                    "id": "9",
                    "contact_id": "10",
                    "address_id": "29",
                    "is_mailing_address": "0",
                    "is_primary_address": "0",
                    "display_priority": "0",
                    "address": {
                        "0": {
                            "id": "29",
                            "address": "6 Road",
                            "address2": "",
                            "city": "TOEOEOWN",
                            "state": "PY",
                            "zip_code": "11116",
                            "country": "USA"
                        }
                    }
                },
                {
                    "id": "10",
                    "contact_id": "10",
                    "address_id": "30",
                    "address": {
                        "0": {
                            "id": "30",
                            "address": "PO Box 9",
                            "address2": "",
                            "city": "TOYN",
                            "state": "GF",
                            "zip_code": "11118",
                            "country": "USA"
                        }
                    }
                }
            ]
        },
        {
            "id": "11",
            "client_id": null,
            "contact_id": "11",
            "addresses": [
                {
                    "id": "11",
                    "contact_id": "11",
                    "address_id": "33",
                    "is_mailing_address": "0",
                    "is_primary_address": "0",
                    "display_priority": "0",
                    "address": {
                        "0": {
                            "id": "33",
                            "address": "4 Street",
                            "address2": "",
                            "city": "TEOIN",
                            "state": "TG",
                            "zip_code": "11119",
                            "country": "USA"
                        }
                    }
                }
            ]
        }
    ]
}

I've tried mapping model fields to what I need (e.g. contacts model > addresses field > mapping: addresses), but this doesn't work because I'd need to map to addresses[0].address[0] to get the data which obviously discards the other addresses.

I've also tried playing around with associations, but this appears to be separate models and stores. The idea here is to not make a separate request for the contacts and then their addresses.

I've also tried digging into the json straight in the template (which seemed to be the most straightforward way) e.g. {addresses.address.city} which doesn't work.

The thinking is simple: grab some json, and display different parts of said json in different parts of the app.

The experience has been dreadful.

Can someone explain how to map these nested json items so that they are accessible from a template?

Template:

{
    xtype: 'container',
    flex: 1,
    id: 'mainPanel',
    items: [
        {
            xtype: 'dataview',
            hidden: false,
            id: 'clientsContacts',
            minHeight: 200,
            itemSelector: 'div',
            itemTpl: [
                '{id} | {last_name} | {first_name} | {relationship} | {addresses}'
            ],
            store: 'Contacts'
        }
    ]
}

Store:

Ext.define('MyApp.store.Contacts', {
    extend: 'Ext.data.Store',

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

    constructor: function(cfg) {
        var me = this;
        cfg = cfg || {};
        me.callParent([Ext.apply({
            autoLoad: false,
            storeId: 'Contacts',
            model: 'MyApp.model.Contacts',
            proxy: {
                type: 'ajax',
                extraParams: {
                    id: '',
                    format: 'json'
                },
                url: '/api/contacts/', //the json
                reader: {
                    type: 'json',
                    root: 'contacts'
                }
            },
            listeners: {
                load: {
                    //fn: me.onJsonstoreLoad,
                    //scope: me
                }
            }
        }, cfg)]);
    },
});

Model:

Ext.define('MyApp.model.Contacts', { extend: 'Ext.data.Model',

    uses: [
        //'MyApp.model.Client',
        //'MyApp.model.contactAddressModel'
    ],

    fields: [
        {
            name: 'client_id'
        },
        {
            name: 'id'
        },
        {
            name: 'addresses',
            mapping: 'addresses'//doesn't work
            //mapping: 'addresses[0].address[0]' //works, but only for the first address duh
        }
    ],
});

Using extjs 4.1 via Sencha Architect.

Any help would be greatly appreciated.

Thanks.

Upvotes: 5

Views: 2972

Answers (2)

James Peruggia
James Peruggia

Reputation: 327

I have verified that the above answer does work, but to note for future people, that if you don't specify the name of sub fields, you don't need the 2nd nested template. You can do it with just the first.

Upvotes: 1

stormdrain
stormdrain

Reputation: 7895

I think I got it (hopefully it's correct).

So, create a field for each nested group of data you need. So I have a Contacts model. In that model there are these fields:

id
client_id
addresses //mapped to addresses
address //mapped to addresses.address 

then in the template:

<br>
<tpl for="addresses">
    id: {id}<br>
    addy id: {address_id}<br>

    <tpl for="address">
        {city} {state}, {zip}<br>
    </tpl>

</tpl>

This is what the whole thing looks like:

View

Ext.define('MyApp.view.MyView', {
    extend: 'Ext.view.View',

    height: 250,
    width: 400,
    itemSelector: 'div',
    store: 'MyJsonStore',

    initComponent: function() {
        var me = this;

        Ext.applyIf(me, {
            itemTpl: [
                '<br>',
                '<tpl for="addresses">',
                '    id: {id}<br>',
                '    addy id: {address_id}<br>',
                '    <b>',
                '    <tpl for="address">',
                '        {city} {state}, {zip}<br><br>',
                '    </tpl>',
                '    </b>',
                '',
                '</tpl>',
                '',
                '<hr>',
                ''
            ]
        });

        me.callParent(arguments);
    }

});

Store

Ext.define('MyApp.store.MyJsonStore', {
    extend: 'Ext.data.Store',

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

    constructor: function(cfg) {
        var me = this;
        cfg = cfg || {};
        me.callParent([Ext.apply({
            storeId: 'MyJsonStore',
            model: 'MyApp.model.Contacts',
            data: {
                contacts: [
                    {
                        id: '1',
                        client_id: '135468714603',
                        addresses: [
                            {
                                id: '1',
                                contact_id: '1',
                                address_id: '16',
                                address: {
                                    '0': {
                                        id: '16',
                                        address: '123 Some Rd',
                                        address2: '',
                                        city: 'Toen',
                                        state: 'VS',
                                        zip_code: '11111',
                                        country: 'USA'
                                    }
                                }
                            },
                            {
                                id: '6',
                                contact_id: '1',
                                address_id: '26',
                                address: {
                                    id: '26',
                                    address: '1 Other Road',
                                    address2: '',
                                    city: 'Twn',
                                    state: 'BD',
                                    zip_code: '11112',
                                    country: 'USA'
                                }
                            }
                        ]
                    },
                    {
                        id: '10',
                        client_id: null,
                        addresses: [
                            {
                                id: '8',
                                contact_id: '10',
                                address_id: '28',
                                address: {
                                    id: '28',
                                    address: '54 Road',
                                    address2: '',
                                    city: 'TWND',
                                    state: 'TT',
                                    zip_code: '11113',
                                    country: 'USA'
                                }
                            },
                            {
                                id: '9',
                                contact_id: '10',
                                address_id: '29',
                                is_mailing_address: '0',
                                is_primary_address: '0',
                                display_priority: '0',
                                address: {
                                    id: '29',
                                    address: '6 Road',
                                    address2: '',
                                    city: 'TOEOEOWN',
                                    state: 'PY',
                                    zip_code: '11116',
                                    country: 'USA'
                                }
                            },
                            {
                                id: '10',
                                contact_id: '10',
                                address_id: '30',
                                address: {
                                    id: '30',
                                    address: 'PO Box 9',
                                    address2: '',
                                    city: 'TOYN',
                                    state: 'GF',
                                    zip_code: '11118',
                                    country: 'USA'
                                }
                            }
                        ]
                    },
                    {
                        id: '11',
                        client_id: null,
                        contact_id: '11',
                        addresses: [
                            {
                                id: '11',
                                contact_id: '11',
                                address_id: '33',
                                is_mailing_address: '0',
                                is_primary_address: '0',
                                display_priority: '0',
                                address: {
                                    id: '33',
                                    address: '4 Street',
                                    address2: '',
                                    city: 'TEOIN',
                                    state: 'TG',
                                    zip_code: '11119',
                                    country: 'USA'
                                }
                            }
                        ]
                    }
                ]
            },
            proxy: {
                type: 'memory',
                reader: {
                    type: 'json',
                    root: 'contacts'
                }
            }
        }, cfg)]);
    }
});

Model

Ext.define('MyApp.model.Contacts', {
    extend: 'Ext.data.Model',

    fields: [
        {
            name: 'id'
        },
        {
            name: 'client_id'
        },
        {
            name: 'addresses',
            mapping: 'addresses'
        },
        {
            name: 'address',
            mapping: 'address'
        }
    ]
});

Upvotes: 4

Related Questions