EXTJS4--Why don't my associated stores load child data?

extjs, extjs-mvc, extjs4

Solution

Put your proxies in your models, unless you have a good reason not to [1]

Make sure you `require` the related model(s), either in the same file, or earlier in the application

Use `foreignKey` if you want to load the related data at will (i.e. with a later network request).

Use `associationKey` if the related data is loaded in the same (nested) response

Or just use both

Always `name` your relationships (otherwise the name will be weird if using namespaces).

Always use the fully qualified model name for the `model` property in your relationships

Working code:

`model/Contact.js`:

Ext.define('Assoc.model.Contact', {
    extend:'Ext.data.Model',

    requires:[
    'Assoc.model.PhoneNumber' 
    ],

    fields:[
    'name' /* automatically has an 'id' field */
    ],

    hasMany:[
    {
        model:'Assoc.model.PhoneNumber', /*use the fully-qualified name here*/
        name:'phoneNumbers', 
        foreignKey:'contact_id',
        associationKey:'phoneNumbers'
    }
    ],

    proxy:{
    type:'ajax',
    url:'assoc/data/contacts.json',
    reader:{
        type:'json',
        root:'data'
    }
    }
});

`model/PhoneNumber.js`:

Ext.define('Assoc.model.PhoneNumber', {
    extend:'Ext.data.Model',

    fields:[
    'number',
    'contact_id'
    ],

    proxy:{
    type:'ajax',
    url:'assoc/data/phone-numbers.json',
    reader:{
        type:'json',
        root:'data'
    }
    }
});

data/contacts.json:

{
    "data":[
    {
    "id":1,
    "name":"neil",
    "phoneNumbers":[
    {
        "id":999,
        "contact_id":1,
        "number":"9005551234"
    }
    ]
    }
    ]

}

data/phone-numbers.json

{
    "data":[
    {
    "id":7,
    "contact_id":1,
    "number":"6045551212"
    },
    {
    "id":88,
    "contact_id":1,
    "number":"8009996541"
    },
    ]

}

`app.js`:

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

Ext.application({

    requires:[
    'Assoc.model.Contact'
    ],

    name:'Assoc',
    appFolder:'Assoc',

    launch:function(){

    /* load child models that are in the response (uses associationKey): */
    Assoc.model.Contact.load(1, {
        success: function(record){
        console.log(record.phoneNumbers());
        }
    });

    /* load child models at will (uses foreignKey). this overwrites child model that are in the first load response */
    Assoc.model.Contact.load(1, {
        success: function(record){
        record.phoneNumbers().load({
            callback:function(){
            console.log(arguments);
            }
        });
        }
    });

    }
});

[1] A store will use its model's proxy. You can always override the store's proxy if need be. You won't be able to use Model.load() if the model has no proxy.

Problem

So I have a parent and child store, illustrated here: Parent Model ``` Ext.define('APP.model.Client', { extend: 'Ext.data.Model', requires: [ 'APP.model.Website', 'Ext.data.association.HasMany', 'Ext.data.association.BelongsTo'], fields: [{ name: 'id', type: 'string' }, { name: 'name', type: 'string' }, { name: 'slug', type: 'string' }, { name: 'active', type: 'boolean' }, { name: 'current', type: 'boolean' }], hasMany: { model: 'APP.model.Website', name: 'websites' } }); ``` Child Model ``` Ext.define('APP.model.Website', { extend: 'Ext.data.Model', fields: [{ name: 'id', type: 'string' }, { name: 'client_id', type: 'string' }, { name: 'sub_domain', type: 'string' }, { name: 'active', type: 'boolean' }], belongsTo: 'APP.model.Client' }); ``` Using an AJAX call via the server, I am loading the `Clients` store, and that is loading fine. But the `Websites` store isn't populated, and when I breakpoint on the `Clients` store on.load function, to see what it's populated with, the `Client` store is only populated with the client data, but in the `raw` property for that store, I can see all the `websites` data. So it's being returned correctly, but my extjs isn't correct. Here are the stores: Client Store ``` Ext.define('APP.store.Clients', { extend: 'Ext.data.Store', autoLoad: false, model: 'APP.model.Client', proxy: { type: 'ajax', url: '/client/list', reader: { type: 'json', root: 'items' } }, sorters: [{ property: 'name', direction: 'ASC' }] }); ``` Websites Store ``` Ext.define('APP.store.Websites', { extend: 'Ext.data.Store', requires: ['Ext.ux.Msg'], autoLoad: false, model: 'APP.model.Website', proxy: { type: 'ajax', url: '/client/list', reader: { type: 'json', root: 'items' }, writer: { type: 'json' } }, sorters: [{ property: 'sub_domain', direction: 'ASC' }] }); ``` My final result is...I would like to populate both stores so I can click on an element, and when it loads something from the parent store, I can access the child store(s) (there will be more when I figure out this problem) to populate a couple grid(s) in tabs. What am I missing as far as my setup? I just downloaded extjs4 a couple days ago, so I am on 4.1.

Original source

Related problems