PDA

View Full Version : Odd issue with Store data



Killmore
16 Jul 2012, 11:39 AM
I have a store that I'm using for a combobox. I'm using store.load in the onLaunch function in my controller. Everything on the surface is working correctly, as in the correct data is showing up in the combobox. But in trying to accomplish something else and digging deeper in something wasn't quite right.

When I run: console.log(store.data)
I see the MixedCollection object with the correct data that was loaded in using the store.load

When I run: console.log(store.data.items[0])
It tells me it is undefined, even though I know there is data there because the combobox is working correctly and the above console run shows the store containing the correct data.

Can someone help explain this discrepancy and how to access the data within the store.

Farish
16 Jul 2012, 10:47 PM
You can get the getRange() method of the store to get an array of all records.


var allRecords = store.getRange();

for(var i=0; i<allRecords.length; i++)
console.log(allRecords[i]);

if you want to access the record using the way you were doing, you have to do store.data.items[0].data. Try printing out the whole store and then you will see where the actual record is.

To get record at some particular index, you can use:

store.getAt(index);

Killmore
17 Jul 2012, 6:49 AM
Farish, unfortunately that did not work. Here is the sample of the code I'm working with so you can get an idea of the problem I'm having.

My store:


Ext.define('Program.store.TeachersList', {
extend: 'Ext.data.Store',
requires: 'Roster.model.Teacher',
model: 'Roster.model.Teacher',

proxy:{
type: 'ajax',
url: 'data/teachers.php',
reader: {
type: 'json',
root: 'results'
}
}
});


My onLaunch function from the controller:


onLaunch: function() {
var teacherStore = this.getTeachersListStore();

teacherStore.load();

console.log(teacherStore.data);// <--- Shows the MixedCollection object of the store with the correct data
console.log(teacherStore.data.items[0]);// <--- Shows undefined
console.log(teacherStore.getRange());// <--- Shows [ ]

var allRecords = teacherStore.getRange();

for(var i=0; i < allRecords.length; i++) {
console.log(allRecords[i]);//<--- Shows nothing since teacherStore.getRange() is returning an empty array
}

},


What is really odd is at console.log(teacherStore.data) I can step through the MixedCollection object and see the data that is there but if I were to run store.getAt(index) it returns nothing.

Actually it was when my store.getAt(index) was returning nothing that prompted me to start looking into this. What really makes this odd is that the combobox that this store is attached to works perfectly fine.

Farish
17 Jul 2012, 7:14 AM
you should put all the things which you want to do with the data on the load event of the store. I guess the store is not loaded and thats why you are having problems:



store.on('load', function() {
console.log(store.getRange());
});

store.load();

Killmore
17 Jul 2012, 8:17 AM
Farish, where your last example does work and I believe I can use it for the problem that I was originally having it hardly explain the strangeness that I'm getting.

I believe the store has been loaded because if it hadn't console.log(store.data) would return a MixedCollection object with 0 items instead of it returning a MixedCollection object with the correct data. It is only when you try to access that data do you start getting all of these undefined and empty arrays.

Anyways thanks for your help.

Farish
17 Jul 2012, 8:19 AM
may be thats a browser or Firebug issue.

Killmore
17 Jul 2012, 8:42 AM
That did peak my interest so I fired up Chrome but alas I have same exact console outputs in both Firebug and Chrome.

I have no idea what is causing it but it is strange that you can console the store and step through it and see the data but, if you actually console the collection it returns nothing and all of the store methods used to access the data return undefined.

scottmartin
18 Jul 2012, 8:09 AM
What is displayed on just: store.data.items

Scott.

Killmore
18 Jul 2012, 9:03 AM
Scott, the only things that appears on store.data.items is [ ]

Which is pretty conclusive of everything else I have seen with this issue. Anything that tries to accesses the MixedCollection object within the store will be returned as empty or undefined. If you look at the store as a whole though the MixedCollection object does contain the correct data.

scottmartin
19 Jul 2012, 5:49 AM
Let's simplify this .. create a small working example that simply loads a JSON string as sent back from the server: ex: url: 'data.json' and see if you get the same result. If so please sent it our way.

Scott.

Killmore
19 Jul 2012, 8:06 AM
Scott, I created a small example using just json data, and the results were exactly the same. I'm attaching the zip file of this test application so you guys can check it out.

scottmartin
19 Jul 2012, 9:08 AM
Here are a few changes .. I have placed notes in the code as well.

37333

Scott.

Killmore
19 Jul 2012, 12:00 PM
Thanks for the updated files, that definitely gives me an idea for the best practices especially concerning when the stores and models should be called and overall layout.

The problem is I was trying to get away from auto loading the store. What I was trying to achieve is the ability to modify the parameters going into the proxy so that I'm only loading the data that I need at run time. Then be able to use this data from the store to say set the default value for the combobox. So since the onLauch function is causing a timing issue, where is the proper place for that type of code?

So to get a visual about what I'm talking about here is a snippet of code from the zip file I sent you:


onLaunch: function() {
var userStore = this.getUsersStore();

if (value == 'something') {
userStore.getProxy().extraParams = {
id: 1
};
} else {
userStore.getProxy().extraParams = {
id: 2
};
}
userStore.load();

userList.select(userStore.data.items[0]);

console.log(userStore.data);
console.log(userStore.data.items);
console.log(userStore.data.items[0]);
console.log(userStore.getRange());

},

I'm sure there is couple of glaring problems in the above code but I'm sure you can get the general idea of what I'm trying to achieve.

Phrosh1
23 Jul 2012, 3:19 AM
I had the exact same issue and figured out how to fix it just a minute ago.
Ext does not seem to wait for the store to be loaded. Instead, it just goes on with the code.

I placed everything record related in the load-listener of the store and it works like a charm!

So, instead of


userStore.load();
userList.select(userStore.data.items[0]);

put
listeners: {load: function(){userList.select(this.first());}}
inside your store config.

I think the reason Firebug shows the correct results is, because we looked it up after the data was already loaded. The code gets executed before...

Killmore
23 Jul 2012, 7:15 AM
That is similar to what I believe farish said earlier up in the thread. I'm still running into odd timing issue like below:

This code is running on another controllers onSelect function:


userStore.on('load', function() {
console.log(userStore.getAt(0)); // <- Showing correctly as an object
userList.select(userStore.getAt(0)); // <- properly selecting the field in the combo box
userList.fireEvent('select', userStore.getAt(0)); // <- firing the select event
})


This code is running on the user controller:


onUserListSelect: function(field, selection) {
console.log(selection[0]); // <- returns undefined :( <sigh>
var selected = selection[0];
}


So you can run the select function in the on load listener of the store and the combo box will show the the selected field correctly. If you use the fireEvent function in the listener you still get an undefined value on the selection variable returned by the combo box. Which makes even less sense now that it is fired within the on load listener.