I want to loop through the objects in a store and remove them if they don't meet some condition, ex:
this.myStore = new Observable(new Memory({identifier: "id", data: []}));
...
array.forEach(this.myStore.data, lang.hitch(this, function(foo){
if (foo.status === Status.REMOVE){
this.myStore.remove(foo.id);
}
else{
this.myStore.get(foo.id).status = Status.NONE;
}
}));
However as soon as I remove a single object in the store, the foo object becomes undefined on the next loop.
Should this be possible or is this the wrong way to do it?
A workaround around I found is to first loop to find the id of the objects I want to remove, and store those in an array. Then I loop a second time on this id array to remove the objects instead of looping on the store data itself. It works, but must I loop twice to do something like this?
Thanks
Use store.query().forEach(...)
instead.
store.data
is the property that dojo/store/Memory
uses internally to store and act upon the data in the store. It is specific to the Memory
store implementation and should generally not be iterated upon directly, especially in these situations, since store.remove
is going to splice elements out of this array, and iterating over an array as its elements are spliced out of itself has interesting undesirable effects:
Array#forEach
, your loop will skip an item each time one at the same or lower index is removed, since it proceeds sequentially through array indices without ever suspecting that items are being spliced out from under it.dojo/_base/array.forEach
, you get the item-skipping behavior and errors, because the functions in dojo/_base/array
cache the length of the array first and just keep going, not expecting that number to change.On the other hand, store.query()
is intended for use cases where you want to iterate over data from your store. The QueryResults
object it returns even provides forEach
and map
functions that you can use regardless of whether you're in an ES5-ready browser and regardless of whether your store is even synchronous (it will run asynchronously once results are retrieved for asynchronous stores). But most importantly, it returns its own array in the case of Memory
, so you don't have to deal with array elements being spliced out from under you.
Runnable example: http://jsfiddle.net/eu6aqxbq/