Skip to content

Instantly share code, notes, and snippets.

@josepjaume
Created April 9, 2014 17:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save josepjaume/10294228 to your computer and use it in GitHub Desktop.
Save josepjaume/10294228 to your computer and use it in GitHub Desktop.
Batch find for ember data - it waits for multiple calls on the same run loop and performs a single request on the API
// Batch find for Ember Data. It will coerce all the finds on the same run loop
// and execute a single batch find for all the records. It mimics the find
// semantics.
//
// Example usage:
//
// var user1 = store.find('user', 1);
// var user2 = store.find('user', 2);
//
// user1.then(function(user){
// console.log(user1.get('firstName'));
// });
//
// user2.then(function(user){
// console.log(user2.get('firstName');
// // circumstancially, this will be available as well:
// console.log(user1.get('firstName');
// });
//
(function(exports){
var findQueues = {};
var FindPromise = Ember.ObjectProxy.extend(Ember.PromiseProxyMixin);
var findMany = function(store, type, ids){
return new Ember.RSVP.Promise(function(resolve){
store.find(type, {ids: ids}).then(function(){
resolve();
});
});
};
var batchFind = function(type, id){
var store = this;
var promise = new Ember.RSVP.Promise(function(resolve){
var cachedModel = store.getById(type, id);
if(cachedModel){
resolve(cachedModel);
}else{
if(!findQueues[type]) findQueues[type] = [];
findQueues[type].push([id, resolve]);
Ember.run.scheduleOnce('afterRender', store, flushFindQueues);
}
});
return FindPromise.create({
content: Ember.Object.create({id: id}),
promise: promise
});
};
var mapIndex = function(array, index){
return array.map(function(element){
return element[index];
});
};
var flushQueue = function(store, key, tasks){
var ids = mapIndex(tasks, 0);
findMany(store, key, ids).then(function(){
tasks.forEach(function(task){
var record = store.getById(key, task[0]);
task[1].call(this, record);
});
});
findQueues[key] = [];
};
var flushFindQueues = function(){
var store = this;
for (var key in findQueues) {
if(findQueues.hasOwnProperty(key)){
var tasks = findQueues[key];
flushQueue(store, key, tasks);
findQueues[key] = [];
}
}
};
exports.Store.reopen({
batchFind: batchFind
});
})(App);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment