View Full Version : problem with datastore change when linked with combobox

25 Oct 2011, 10:33 PM
I have a strange problem. I have a combobox called products and a datastore called productMilestones. I need to change the content of productMilestones when the value of products combo is changed. Follwing is a code snippet of how I have loaded productMilestones:
var productMilestones = Ext.data.StoreManager.lookup('productMilestones');
productMilestones.sort('display_order', 'ASC');

When I throw the output to console (i.e. console.log(productMilestones)), I can see full data, but when I try to access it from my script, e.g. productMilestones.data.length, I get 0 whilst in the console, it shows correct data, i.e. 4 in my particular case.

Can anybody please tell me why this is happening? Thanks in advance!


26 Oct 2011, 3:09 AM
Guessing a bit but...

The store load is asynchronous. If you try to access the contents of the store immediately after calling load() it won't have loaded yet.

When you dig into an object in the console it will be the current version, not necessarily the same as it was at the time you logged it out. So when it was logged it was empty but by the time you view it in the console the Ajax request will have completed and the data will be there.

Does that fit with what you're actually doing?

Instead of logging out the entire store try logging out a primitive property, something like this:


The value of a primitive can't change so there's no risk of you running into the 'liveness' problem.

26 Oct 2011, 8:00 AM
Thanks for the reply. I understand that ajax request takes time for processing. After the load function for the store is called, I have kept some delay, and the data sent received when checking in firebug is also correct. By introducing a delay, theoretically, I think it should work, but it doesn't. My code is something like this:

productMilestones.proxy.url = 'test/milestones.php?productID='+selectedProduct;
productMilestones.sort('display_order', 'ASC');
load users linked with the current company
msg: 'Loading your data, please wait...',
progressText: 'Loading...',
waitConfig: {interval:500}
}, 500);


The getCount function produces 0, so does datastore.data.length.

Rest of processing the content of the store is done after this code. I think the delay should help, but it is not. But, when I select a different value in the combo box, it works this time.

Its just crazy. I don't understand how and why.

Tim Toady
26 Oct 2011, 1:10 PM
Use a listener for the load event and do your getCount()/processing there. You shouldn't try to guess the amount of time it takes. I don't see the getCount at all in your code (Please use code tags with brackets around your code next time so it is more readable). Also, that setTimeout isn't going to stop all JS from running. It just waits until the time has passed to call the hide function and continues working on code after the call in the mean time.

26 Oct 2011, 8:50 PM
CODE tags need to be surrounded by square brackets, not angle braces:

From the code you've posted I'd agree with Tim Toady. I don't see any evidence of a meaningful delay in your code but without the console.log() it's difficult to be sure.

An alternative to using a load event is to provide a callback to the load() method.

6 Nov 2011, 8:45 PM
Hi All,
Thanks for your replies. My initial idea was to populate a datastore when a value in combobox changes, and use that datastore to populate the datastore of a grid. I think this is multiple step operation, so scrapped it.

As skirtle has said, I loaded the datastore of the grid directly when the value in combobox changes. And when the data is loaded in datastore, it calls onload event of the datastore. Here, I have filled in data in the empty columns of the datastore. The change made in datastore should be visible, but it is not. Can you help me with this?

My code is as follows:

onProductChange:function(combo, value, options )
var cmbProduct = this.getComponent('fsProduct').getComponent('Product');
var selectedProduct = combo.value;
var gridSchedule = this.getComponent('cnSchedules').getComponent('cnScheduleList').getComponent('gridSchedule');

if(selectedProduct > 0)
var btnAdd = this.getComponent('cnSchedules').getComponent('btnContainer').getComponent('btnAdd');

var btnReset = this.getComponent('cnSchedules').getComponent('cnScheduleList').getComponent('btnReset');

btnReset.on('click', this.resetScheduleGrid, this);

var productMilestones = Ext.data.StoreManager.lookup('productMilestoneStore');
productMilestones.proxy.url = 'test/milestones.php?productID='+selectedProduct;
productMilestones.sort('display_order', 'ASC');
productMilestones.on('load', this.addProductMilestone, this);

and the function called when data is loaded in the store:

addProductMilestone:function(dataStore, records, successful, operation, options)
var newDate = new Date();
for(i = 0; i < records.length; i++)
var row = records[i].data;
row.milestone_id = row.milestone_id;
row.name = row.name;
row.display_order = row.display_order;
row.assigned_company_id = this.compID;
row.branch_id = 0;
row.task_user_id = 0;
row.updatefacility = 10;
row.update_date = newDate;

In the grid, only the first column is populated, the rest aren't whilst console.log shows complete data in the store.

7 Nov 2011, 5:09 PM
Try something like this:

addProductMilestone: function(dataStore, records) {
var date = new Date();

for (var i = 0; i < records.length; i++) {
var record = records[i];

assigned_company_id: this.compID,
branch_id: 0,
task_user_id: 0,
updatefacility: 10,
update_date: date


7 Nov 2011, 9:42 PM
Thanks Skirtle! That solved my problem!