PDA

View Full Version : Using data from association in convert function.



Berzzzebub
27 Aug 2011, 3:26 AM
Hello community.
I'm trying to use data from association in convert function but encountered with very strange behavior of store with association data that I can not explain.

I have two models:


Ext.define('my.model.LabeledAddress', {
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'string'},
{name: 'value', type: 'string'},
{name: 'contact_id', type: 'string'}
]
});
and


Ext.define('my.model.Contact', {
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'string'},
{name: 'caption', type: 'string'},
{name: 'picture', type: 'string'},
{name: 'state', type: 'string', defaultValue: 'offline'},
{
name: 'labAddrs',
type: 'string',
convert: function(value, record) {
var addresses = record.labeledAddresses();
var val = '';
console.log(addresses); //Normal Store object with associated items
console.log(addresses.count()); //Returns 0
addresses.each(function(rec) {
val.concat(rec.get('value'), ' '); //Never called
});
return val;
}
}
],
associations: [
{type: 'hasMany', model: 'my.model.LabeledAddress', name: 'labeledAddresses', foreignKey: 'contact_id'}
],
proxy: {
type: 'ajax',
api: {
read: '/my_client/get_contacts'
}
}
});

In second one (Contact) I want to create field that will return concatenation of associated addresses values. As I mentioned in comment in code, record.labeledAddresses() returns normal store object, that contains all needed data, but when I'm trying to fetch it, the store behaves like absolutely empty.

An example of JSON, that returns from /my_client/get_contacts:


{
"id":"4dd0e431e73b361ad2000098",
"caption":"Administrator",
"picture":"images/DefaultAvatar.png",
"labeledAddresses":
[
{"id":"4e55fea1e73b3633d700014a","contact_id":"4dd0e431e73b361ad2000098","value":"202"},
{"id":"4e55fea1e73b3633d700014c","contact_id":"4dd0e431e73b361ad2000098","value":"204"}
],
"directory_id":"4dd0e431e73b361ad2000097"
}

What am I doing wrong? I would be grateful for any advice.

skirtle
27 Aug 2011, 7:08 AM
My guess would be that it processes the fields before it populates the association. From the docs:

http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.Field-cfg-convert


rec : Ext.data.Model

The data object containing the Model as read so far by the Reader. Note that the Model may not be fully populated at this point as the fields are read in the order that they are defined in your fields array.

I haven't dug in to confirm but my guess would be that the associations are done after all the fields.

One way you would be able to do it is to set the mapping for your field to labeledAddresses, then the convert function will be passed the raw data array of values.

Berzzzebub
28 Aug 2011, 1:55 PM
Many thanks for your reply, skirtle. I followed your advice and now everything works fine.
Code in Contacts model now looks like:

Ext.define('my.model.Contact', {
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'string'},
{name: 'caption', type: 'string'},
{name: 'picture', type: 'string'},
{name: 'state', type: 'string', defaultValue: 'offline'},
{name: 'mappedAddresses', mapping: 'labeledAddresses'},
{
name: 'addrsValues',
type: 'string',
convert: function(value, record) {
var addresses = record.get('mappedAddresses');
var val = '';
for(var i = 0; i < addresses.length; i++){
val = val.concat(addresses[i].value);
if(i < addresses.length - 1){
val = val.concat(', ');
}
}
return val;
}
}
],
associations: [
{type: 'hasMany', model: 'my.model.LabeledAddress', name: 'labeledAddresses', foreignKey: 'contact_id'}
],
proxy: {
type: 'ajax',
api: {
read: '/my_client/get_contacts'
}
}
});

skirtle
28 Aug 2011, 10:45 PM
Couldn't you just do this?


{
mapping: 'labeledAddresses'
name: 'addrsValues',
convert: function(value) {
return Ext.Array.pluck(value, 'value').join(', ');
}
}

Berzzzebub
28 Aug 2011, 10:50 PM
Yes, it works :) Thanks!

Experience and practice - a great things.