Skip to content

Commit

Permalink
feat(preload): adds support for query parameters.
Browse files Browse the repository at this point in the history
Closes #152
  • Loading branch information
iobaixas committed Sep 24, 2014
1 parent bf05802 commit 62f1dcb
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 14 deletions.
36 changes: 26 additions & 10 deletions src/plugins/preload.js
Expand Up @@ -9,16 +9,16 @@
angular.module('restmod').factory('restmod.Preload', ['restmod', '$q', function(restmod, $q) {

// simple populate implementation for models that do not provide a $populate function
function populate(_records) {
function populate(_records, _params) {
var promises = [];
for(var i = 0; i < _records.length; i++) {
promises.push(_records[i].$resolve().$asPromise());
promises.push(_records[i].$resolve(_params).$asPromise());
}
return $q.all(promises);
}

// processes a group records of the same type
function processGroup(_records, _target) {
function processGroup(_records, _target, _params) {

// extract targets
var targets = [], record;
Expand All @@ -34,8 +34,8 @@ angular.module('restmod').factory('restmod.Preload', ['restmod', '$q', function(
// populate targets
if(targets.length > 0) {
var promise = typeof targets[0].$type.$populate === 'function' ?
targets[0].$type.$populate(targets).$asPromise() :
populate(targets);
targets[0].$type.$populate(targets, _params).$asPromise() :
populate(targets, _params);

if(promise) {
return promise.then(function() {
Expand All @@ -48,9 +48,9 @@ angular.module('restmod').factory('restmod.Preload', ['restmod', '$q', function(
}

// helper factory that binds processGroup to a target.
function processGroupAsync(_target) {
function processGroupAsync(_target, _params) {
return function(_records) {
return processGroup(_records, _target);
return processGroup(_records, _target, _params);
};
}

Expand All @@ -76,6 +76,16 @@ angular.module('restmod').factory('restmod.Preload', ['restmod', '$q', function(
* simple resolving. Take a look at the Populate plugin for a $populate implementation using special
* API support.
*
* It is also posible to specify some query parameters to be passed to the $populate/$resolve methods
* using an extended form:
*
* ```javascript
* Bike.$search({ category: 'xc' }).$preload(
* 'user',
* { path 'parts', params: { include: 'maker' } }, // path is the relation name and params the parameters
* );
* ```
*
* @param {array} arguments Relations to preload.
* @return {Resource} self
*/
Expand All @@ -89,7 +99,13 @@ angular.module('restmod').factory('restmod.Preload', ['restmod', '$q', function(
parent, name, fullName, tailPromise;

for(var i = 0; i < targets.length; i++) {
var target = targets[i];
var target = targets[i], params;

if(typeof target === 'object') {
params = target.params;
target = target.path;
}

if(targetCache[target]) continue; // already preloaded

parent = '';
Expand All @@ -103,10 +119,10 @@ angular.module('restmod').factory('restmod.Preload', ['restmod', '$q', function(
if(!targetCache[fullName]) {
if(tailPromise) {
// queue after parent request
tailPromise = tailPromise.then(processGroupAsync(name));
tailPromise = tailPromise.then(processGroupAsync(name, params));
} else {
// execute immediately
tailPromise = processGroup(initialGroup, name);
tailPromise = processGroup(initialGroup, name, params);
}

targetCache[fullName] = tailPromise;
Expand Down
22 changes: 18 additions & 4 deletions test/plugins/preload-spec.js
Expand Up @@ -45,16 +45,30 @@ describe('Plugin: Preload function', function() {
jasmine.objectContaining({ $pk: 10 }),
jasmine.objectContaining({ $pk: 11 }),
jasmine.objectContaining({ $pk: 13 })
]);
], undefined);
expect(User.$populate.callCount).toEqual(1);
});

it('should support parameters', function() {
User.$populate = jasmine.createSpy().andReturn(User.dummy(true));

bikes.$preload({ path: 'user', params: { include: 'all' } });
expect(User.$populate).toHaveBeenCalledWith([
jasmine.objectContaining({ $pk: 10 }),
jasmine.objectContaining({ $pk: 11 }),
jasmine.objectContaining({ $pk: 13 })
], { include: 'all' });
});

it('should work on single records too', function() {
var bike = Bike.$new(1).$decode({ userId: 10, brand: 'Santa Cruz' });
User.$populate = jasmine.createSpy().andReturn(User.dummy(true));

bike.$preload('user');
expect(User.$populate).toHaveBeenCalledWith([ jasmine.objectContaining({ $pk: 10 }) ]);
expect(User.$populate).toHaveBeenCalledWith(
[ jasmine.objectContaining({ $pk: 10 }) ],
undefined
);
});

it('should properly manager hierachies', function() {
Expand All @@ -73,14 +87,14 @@ describe('Plugin: Preload function', function() {
jasmine.objectContaining({ $pk: 1 }),
jasmine.objectContaining({ $pk: 5 }),
jasmine.objectContaining({ $pk: 5 })
]);
], undefined);

expect(User.$populate.callCount).toEqual(2);
expect(User.$populate).toHaveBeenCalledWith([
jasmine.objectContaining({ $pk: 1 }),
jasmine.objectContaining({ $pk: 2 }),
jasmine.objectContaining({ $pk: 3 })
]);
], undefined);

});

Expand Down

0 comments on commit 62f1dcb

Please sign in to comment.