Skip to content

Commit ee62196

Browse files
committed
Closes #56.
1 parent 1d1e542 commit ee62196

File tree

8 files changed

+447
-34
lines changed

8 files changed

+447
-34
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
- #50 - DS.bindAll($scope, prop, resourceName, query)
77
- #52 - DS.update(resourceName, id, attrs[, options]) (different from DS.save())
88
- #54 - Adding functionality to resources
9+
- #56 - DS.updateAll(resourceName, attrs, params[, options])
910

1011
##### 0.8.1 - 02 May 2014
1112

dist/angular-data.js

Lines changed: 188 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1486,9 +1486,24 @@ function DSHttpAdapterProvider() {
14861486
*/
14871487
update: update,
14881488

1489-
updateMany: function () {
1490-
throw new Error('Not yet implemented!');
1491-
},
1489+
/**
1490+
* @doc method
1491+
* @id DSHttpAdapter.methods:updateAll
1492+
* @name updateAll
1493+
* @description
1494+
* Update a collection of entities on the server.
1495+
*
1496+
* Sends a `PUT` request to `:baseUrl/:endpoint`.
1497+
*
1498+
*
1499+
* @param {object} resourceConfig Properties:
1500+
* - `{string}` - `baseUrl` - Base url.
1501+
* - `{string=}` - `endpoint` - Endpoint path for the resource.
1502+
* @param {object=} params Search query parameters. See the [query guide](/documentation/guide/queries/index).
1503+
* @param {object=} options Optional configuration. Refer to the documentation for `$http.put`.
1504+
* @returns {Promise} Promise.
1505+
*/
1506+
updateAll: updateAll,
14921507

14931508
/**
14941509
* @doc method
@@ -1609,6 +1624,20 @@ function DSHttpAdapterProvider() {
16091624
);
16101625
}
16111626

1627+
function updateAll(resourceConfig, attrs, params, options) {
1628+
options = options || {};
1629+
options.params = options.params || {};
1630+
if (options.params.query) {
1631+
options.params.query = defaults.queryTransform(options.params.query);
1632+
}
1633+
DSUtils.deepMixIn(options, params);
1634+
return this.PUT(
1635+
DSUtils.makePath(resourceConfig.baseUrl, resourceConfig.endpoint),
1636+
defaults.serialize(attrs),
1637+
options
1638+
);
1639+
}
1640+
16121641
function destroy(resourceConfig, id, options) {
16131642
options = options || {};
16141643
return this.DEL(
@@ -2260,10 +2289,20 @@ module.exports = {
22602289
* @description
22612290
* See [DS.update](/documentation/api/api/DS.async_methods:update).
22622291
*/
2263-
update: require('./update')
2292+
update: require('./update'),
2293+
2294+
/**
2295+
* @doc method
2296+
* @id DS.async_methods:updateAll
2297+
* @name updateAll
2298+
* @methodOf DS
2299+
* @description
2300+
* See [DS.updateAll](/documentation/api/api/DS.async_methods:updateAll).
2301+
*/
2302+
updateAll: require('./updateAll')
22642303
};
22652304

2266-
},{"./create":32,"./destroy":33,"./destroyAll":34,"./find":35,"./findAll":36,"./refresh":38,"./save":39,"./update":40}],38:[function(require,module,exports){
2305+
},{"./create":32,"./destroy":33,"./destroyAll":34,"./find":35,"./findAll":36,"./refresh":38,"./save":39,"./update":40,"./updateAll":41}],38:[function(require,module,exports){
22672306
var errorPrefix = 'DS.refresh(resourceName, id[, options]): ';
22682307

22692308
/**
@@ -2550,10 +2589,10 @@ function save(resourceName, id, attrs, options) {
25502589
})
25512590
.then(function (data) {
25522591
if (options.cacheResponse) {
2553-
_this.inject(definition.name, data, options);
2592+
var item = _this.inject(definition.name, data, options);
25542593
resource.previousAttributes[id] = _this.utils.deepMixIn({}, data);
25552594
resource.saved[id] = _this.utils.updateTimestamp(resource.saved[id]);
2556-
return _this.get(resourceName, id);
2595+
return item;
25572596
} else {
25582597
return data;
25592598
}
@@ -2567,6 +2606,129 @@ function save(resourceName, id, attrs, options) {
25672606
module.exports = save;
25682607

25692608
},{}],41:[function(require,module,exports){
2609+
var errorPrefix = 'DS.updateAll(resourceName, attrs, params[, options]): ';
2610+
2611+
/**
2612+
* @doc method
2613+
* @id DS.async_methods:updateAll
2614+
* @name updateAll
2615+
* @description
2616+
* Update items of type `resourceName` with `attrs` according to the criteria specified by `params`. This is useful when
2617+
* you want to update multiple items with the same attributes that aren't already in the data store, or you don't want
2618+
* to update the items that are in the data store until the server-side operation succeeds.
2619+
*
2620+
* ## Signature:
2621+
* ```js
2622+
* DS.updateAll(resourceName, attrs, params[, options])
2623+
* ```
2624+
*
2625+
* ## Example:
2626+
*
2627+
* ```js
2628+
* DS.filter('document'); // []
2629+
*
2630+
* DS.updateAll('document', 5, { author: 'Sally' }, {
2631+
* query: {
2632+
* where: {
2633+
* author: {
2634+
* '==': 'John Anderson'
2635+
* }
2636+
* }
2637+
* }
2638+
* })
2639+
* .then(function (documents) {
2640+
* documents; // The documents that were updated on the server
2641+
* // and now reside in the data store
2642+
*
2643+
* documents[0].author; // "Sally"
2644+
* });
2645+
* ```
2646+
*
2647+
* @param {string} resourceName The resource type, e.g. 'user', 'comment', etc.
2648+
* @param {object} attrs The attributes with which to update the items.
2649+
* @param {object} params Parameter object that is serialized into the query string. Properties:
2650+
*
2651+
* - `{object=}` - `query` - The query object by which to filter items of the type specified by `resourceName`. Properties:
2652+
* - `{object=}` - `where` - Where clause.
2653+
* - `{number=}` - `limit` - Limit clause.
2654+
* - `{skip=}` - `skip` - Skip clause.
2655+
* - `{orderBy=}` - `orderBy` - OrderBy clause.
2656+
*
2657+
* @param {object=} options Optional configuration. Properties:
2658+
* - `{boolean=}` - `cacheResponse` - Inject the data returned by the server into the data store. Default: `true`.
2659+
*
2660+
* @returns {Promise} Promise produced by the `$q` service.
2661+
*
2662+
* ## Resolves with:
2663+
*
2664+
* - `{object}` - `item` - A reference to the newly saved item.
2665+
*
2666+
* ## Rejects with:
2667+
*
2668+
* - `{IllegalArgumentError}`
2669+
* - `{RuntimeError}`
2670+
* - `{UnhandledError}`
2671+
*/
2672+
function save(resourceName, attrs, params, options) {
2673+
var deferred = this.$q.defer(),
2674+
promise = deferred.promise;
2675+
2676+
options = options || {};
2677+
2678+
if (!this.definitions[resourceName]) {
2679+
deferred.reject(new this.errors.RuntimeError(errorPrefix + resourceName + ' is not a registered resource!'));
2680+
} else if (!this.utils.isObject(attrs)) {
2681+
deferred.reject(new this.errors.IllegalArgumentError(errorPrefix + 'attrs: Must be an object!'));
2682+
} else if (!this.utils.isObject(params)) {
2683+
deferred.reject(new this.errors.IllegalArgumentError(errorPrefix + 'params: Must be an object!'));
2684+
} else if (!this.utils.isObject(options)) {
2685+
deferred.reject(new this.errors.IllegalArgumentError(errorPrefix + 'options: Must be an object!'));
2686+
} else {
2687+
var definition = this.definitions[resourceName],
2688+
resource = this.store[resourceName],
2689+
_this = this;
2690+
2691+
if (!('cacheResponse' in options)) {
2692+
options.cacheResponse = true;
2693+
} else {
2694+
options.cacheResponse = !!options.cacheResponse;
2695+
}
2696+
2697+
promise = promise
2698+
.then(function (attrs) {
2699+
return _this.$q.promisify(definition.beforeValidate)(resourceName, attrs);
2700+
})
2701+
.then(function (attrs) {
2702+
return _this.$q.promisify(definition.validate)(resourceName, attrs);
2703+
})
2704+
.then(function (attrs) {
2705+
return _this.$q.promisify(definition.afterValidate)(resourceName, attrs);
2706+
})
2707+
.then(function (attrs) {
2708+
return _this.$q.promisify(definition.beforeUpdate)(resourceName, attrs);
2709+
})
2710+
.then(function (attrs) {
2711+
return _this.adapters[options.adapter || definition.defaultAdapter].updateAll(definition, attrs, params, options);
2712+
})
2713+
.then(function (data) {
2714+
return _this.$q.promisify(definition.afterUpdate)(resourceName, data);
2715+
})
2716+
.then(function (data) {
2717+
if (options.cacheResponse) {
2718+
return _this.inject(definition.name, data, options);
2719+
} else {
2720+
return data;
2721+
}
2722+
});
2723+
2724+
deferred.resolve(attrs);
2725+
}
2726+
return promise;
2727+
}
2728+
2729+
module.exports = save;
2730+
2731+
},{}],42:[function(require,module,exports){
25702732
var utils = require('../utils')[0]();
25712733

25722734
function lifecycleNoop(resourceName, attrs, cb) {
@@ -2776,7 +2938,7 @@ function DSProvider() {
27762938

27772939
module.exports = DSProvider;
27782940

2779-
},{"../utils":"K0yknU","./async_methods":37,"./sync_methods":52}],42:[function(require,module,exports){
2941+
},{"../utils":"K0yknU","./async_methods":37,"./sync_methods":53}],43:[function(require,module,exports){
27802942
var errorPrefix = 'DS.bindAll(scope, expr, resourceName, params): ';
27812943

27822944
/**
@@ -2848,7 +3010,7 @@ function bindOne(scope, expr, resourceName, params) {
28483010

28493011
module.exports = bindOne;
28503012

2851-
},{}],43:[function(require,module,exports){
3013+
},{}],44:[function(require,module,exports){
28523014
var errorPrefix = 'DS.bindOne(scope, expr, resourceName, id): ';
28533015

28543016
/**
@@ -2908,7 +3070,7 @@ function bindOne(scope, expr, resourceName, id) {
29083070

29093071
module.exports = bindOne;
29103072

2911-
},{}],44:[function(require,module,exports){
3073+
},{}],45:[function(require,module,exports){
29123074
var errorPrefix = 'DS.changes(resourceName, id): ';
29133075

29143076
/**
@@ -2965,7 +3127,7 @@ function changes(resourceName, id) {
29653127

29663128
module.exports = changes;
29673129

2968-
},{}],45:[function(require,module,exports){
3130+
},{}],46:[function(require,module,exports){
29693131
/*jshint evil:true*/
29703132
var errorPrefix = 'DS.defineResource(definition): ';
29713133

@@ -3102,7 +3264,7 @@ function defineResource(definition) {
31023264

31033265
module.exports = defineResource;
31043266

3105-
},{}],46:[function(require,module,exports){
3267+
},{}],47:[function(require,module,exports){
31063268
var observe = require('observejs');
31073269

31083270
/**
@@ -3144,7 +3306,7 @@ function digest() {
31443306

31453307
module.exports = digest;
31463308

3147-
},{"observejs":"QYwGEY"}],47:[function(require,module,exports){
3309+
},{"observejs":"QYwGEY"}],48:[function(require,module,exports){
31483310
var errorPrefix = 'DS.eject(resourceName, id): ';
31493311

31503312
function _eject(definition, resource, id) {
@@ -3227,7 +3389,7 @@ function eject(resourceName, id) {
32273389

32283390
module.exports = eject;
32293391

3230-
},{}],48:[function(require,module,exports){
3392+
},{}],49:[function(require,module,exports){
32313393
var errorPrefix = 'DS.ejectAll(resourceName[, params]): ';
32323394

32333395
function _ejectAll(definition, resource, params) {
@@ -3331,7 +3493,7 @@ function ejectAll(resourceName, params) {
33313493

33323494
module.exports = ejectAll;
33333495

3334-
},{}],49:[function(require,module,exports){
3496+
},{}],50:[function(require,module,exports){
33353497
/* jshint loopfunc: true */
33363498
var errorPrefix = 'DS.filter(resourceName, params[, options]): ';
33373499

@@ -3488,7 +3650,7 @@ function filter(resourceName, params, options) {
34883650

34893651
module.exports = filter;
34903652

3491-
},{}],50:[function(require,module,exports){
3653+
},{}],51:[function(require,module,exports){
34923654
var errorPrefix = 'DS.get(resourceName, id[, options]): ';
34933655

34943656
/**
@@ -3551,7 +3713,7 @@ function get(resourceName, id, options) {
35513713

35523714
module.exports = get;
35533715

3554-
},{}],51:[function(require,module,exports){
3716+
},{}],52:[function(require,module,exports){
35553717
var errorPrefix = 'DS.hasChanges(resourceName, id): ';
35563718

35573719
function diffIsEmpty(utils, diff) {
@@ -3614,7 +3776,7 @@ function hasChanges(resourceName, id) {
36143776

36153777
module.exports = hasChanges;
36163778

3617-
},{}],52:[function(require,module,exports){
3779+
},{}],53:[function(require,module,exports){
36183780
module.exports = {
36193781
/**
36203782
* @doc method
@@ -3757,7 +3919,7 @@ module.exports = {
37573919
hasChanges: require('./hasChanges')
37583920
};
37593921

3760-
},{"./bindAll":42,"./bindOne":43,"./changes":44,"./defineResource":45,"./digest":46,"./eject":47,"./ejectAll":48,"./filter":49,"./get":50,"./hasChanges":51,"./inject":53,"./lastModified":54,"./lastSaved":55,"./previous":56}],53:[function(require,module,exports){
3922+
},{"./bindAll":43,"./bindOne":44,"./changes":45,"./defineResource":46,"./digest":47,"./eject":48,"./ejectAll":49,"./filter":50,"./get":51,"./hasChanges":52,"./inject":54,"./lastModified":55,"./lastSaved":56,"./previous":57}],54:[function(require,module,exports){
37613923
var observe = require('observejs'),
37623924
errorPrefix = 'DS.inject(resourceName, attrs[, options]): ';
37633925

@@ -3907,7 +4069,7 @@ function inject(resourceName, attrs, options) {
39074069

39084070
module.exports = inject;
39094071

3910-
},{"observejs":"QYwGEY"}],54:[function(require,module,exports){
4072+
},{"observejs":"QYwGEY"}],55:[function(require,module,exports){
39114073
var errorPrefix = 'DS.lastModified(resourceName[, id]): ';
39124074

39134075
/**
@@ -3965,7 +4127,7 @@ function lastModified(resourceName, id) {
39654127

39664128
module.exports = lastModified;
39674129

3968-
},{}],55:[function(require,module,exports){
4130+
},{}],56:[function(require,module,exports){
39694131
var errorPrefix = 'DS.lastSaved(resourceName[, id]): ';
39704132

39714133
/**
@@ -4026,7 +4188,7 @@ function lastSaved(resourceName, id) {
40264188

40274189
module.exports = lastSaved;
40284190

4029-
},{}],56:[function(require,module,exports){
4191+
},{}],57:[function(require,module,exports){
40304192
var errorPrefix = 'DS.previous(resourceName, id): ';
40314193

40324194
/**
@@ -4254,7 +4416,7 @@ module.exports = [function () {
42544416
};
42554417
}];
42564418

4257-
},{}],59:[function(require,module,exports){
4419+
},{}],60:[function(require,module,exports){
42584420
(function (window, angular, undefined) {
42594421
'use strict';
42604422

@@ -4282,7 +4444,7 @@ module.exports = [function () {
42824444
* Load `dist/angular-data.js` or `dist/angular-data.min.js` onto your web page after Angular.js.
42834445
*
42844446
* #### Manual download
4285-
* Download angular-data.0.9.0-SNAPSHOT.js from the [Releases](https://github.com/jmdobry/angular-data/releases)
4447+
* Download angular-data.0.9.0.js from the [Releases](https://github.com/jmdobry/angular-data/releases)
42864448
* section of the angular-data GitHub project.
42874449
*
42884450
* ## Load into Angular
@@ -4336,7 +4498,7 @@ module.exports = [function () {
43364498

43374499
})(window, window.angular);
43384500

4339-
},{"./adapters/http":31,"./datastore":41,"./errors":"XIsZmp","./utils":"K0yknU"}],"K0yknU":[function(require,module,exports){
4501+
},{"./adapters/http":31,"./datastore":42,"./errors":"XIsZmp","./utils":"K0yknU"}],"K0yknU":[function(require,module,exports){
43404502
module.exports = [function () {
43414503
return {
43424504
isString: angular.isString,
@@ -4420,4 +4582,4 @@ module.exports = [function () {
44204582

44214583
},{"mout/array/contains":3,"mout/array/filter":4,"mout/array/slice":8,"mout/array/sort":9,"mout/array/toLookup":10,"mout/lang/isEmpty":15,"mout/object/deepMixIn":22,"mout/object/forOwn":24,"mout/object/pick":27,"mout/object/set":28,"mout/string/makePath":29,"mout/string/upperCase":30}],"utils":[function(require,module,exports){
44224584
module.exports=require('K0yknU');
4423-
},{}]},{},[59])
4585+
},{}]},{},[60])

dist/angular-data.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)