From 62f1dcb136652bfb3e413749c67d1b4443958d07 Mon Sep 17 00:00:00 2001 From: Ignacio Baixas Date: Wed, 24 Sep 2014 11:57:13 -0300 Subject: [PATCH] feat(preload): adds support for query parameters. Closes #152 --- src/plugins/preload.js | 36 ++++++++++++++++++++++++++---------- test/plugins/preload-spec.js | 22 ++++++++++++++++++---- 2 files changed, 44 insertions(+), 14 deletions(-) diff --git a/src/plugins/preload.js b/src/plugins/preload.js index 1b757be..2aad372 100644 --- a/src/plugins/preload.js +++ b/src/plugins/preload.js @@ -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; @@ -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() { @@ -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); }; } @@ -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 */ @@ -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 = ''; @@ -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; diff --git a/test/plugins/preload-spec.js b/test/plugins/preload-spec.js index 655ec08..5d806c6 100644 --- a/test/plugins/preload-spec.js +++ b/test/plugins/preload-spec.js @@ -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() { @@ -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); });