Skip to content

Commit 768d718

Browse files
committed
More fixes.
1 parent 786b5cb commit 768d718

File tree

9 files changed

+318
-248
lines changed

9 files changed

+318
-248
lines changed

karma.start.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ var fail = function (msg) {
1515
TYPES_EXCEPT_BOOLEAN = ['string', 123, 123.123, null, undefined, {}, [], function () {}],
1616
TYPES_EXCEPT_FUNCTION = ['string', 123, 123.123, null, undefined, {}, [], true, false];
1717

18-
angular.module('jmdobry.angular-data', ['ng', 'jmdobry.binary-heap', 'ngMock']);
18+
angular.module('jmdobry.angular-data', ['ng', /*'jmdobry.binary-heap',*/ 'ngMock']);
1919

2020
beforeEach(module('jmdobry.angular-data'));
2121

src/datastore/async_methods/find/index.js

Lines changed: 53 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,66 +2,86 @@ var utils = require('utils'),
22
errors = require('errors'),
33
store = require('store'),
44
services = require('services'),
5-
GET = require('../../HTTP').GET;
5+
GET = require('../../HTTP').GET,
6+
errorPrefix = 'DS.find(resourceName, id[, options]): ';
67

78
/**
89
* @doc method
910
* @id DS.async_methods:find
1011
* @name find
1112
* @description
12-
* `find(resourceName, id[, forceRefresh])`
13-
*
1413
* Asynchronously return the resource with the given id from the server. The result will be added to the data
1514
* store when it returns from the server.
1615
*
17-
* Example:
16+
* ## Signature:
17+
* ```js
18+
* DS.find(resourceName, id[, options])
19+
* ```
20+
*
21+
* ## Example:
1822
*
1923
* ```js
20-
* TODO: find(resourceName, id[, forceRefresh]) example
24+
* DS.get('document', 5); // undefined
25+
* DS.find('document', 5).then(function (document) {
26+
* document; // { id: 5, author: 'John Anderson' }
27+
*
28+
* DS.get('document', 5); // { id: 5, author: 'John Anderson' }
29+
* }, function (err) {
30+
* // Handled errors
31+
* });
2132
* ```
2233
*
2334
* @param {string} resourceName The resource type, e.g. 'user', 'comment', etc.
2435
* @param {string|number} id The primary key of the item to retrieve.
25-
* @param {boolean=} forceRefresh Bypass the cache.
36+
* @param {object=} options Optional configuration. Properties:
37+
* - `{boolean=}` - `bypassCache` - Bypass the cache. Default: `false`.
38+
* - `{string=}` - `mergeStrategy` - If `findAll` is called, specify the merge strategy that should be used when the new
39+
* items are injected into the data store. Default: `"mergeWithExisting"`.
2640
* @returns {Promise} Promise produced by the `$q` service.
2741
*
28-
* ## ResolvesWith:
42+
* ## Resolves with:
2943
*
30-
* - `{array}` - `item` - The item with the primary key specified by `id`.
44+
* - `{object}` - `item` - The item with the primary key specified by `id`.
3145
*
32-
* ## RejectsWith:
46+
* ## Rejects with:
3347
*
34-
* - `{IllegalArgumentError}` - `err` - Argument `id` must be a string or a number.
35-
* - `{RuntimeError}` - `err` - Argument `resourceName` must refer to an already registered resource.
36-
* - `{UnhandledError}` - `err` - Thrown for any uncaught exception.
48+
* - `{IllegalArgumentError}`
49+
* - `{RuntimeError}`
50+
* - `{UnhandledError}`
3751
*/
38-
function find(resourceName, id, forceRefresh) {
52+
function find(resourceName, id, options) {
3953
var deferred = $q.defer();
4054
if (!store[resourceName]) {
41-
deferred.reject(new errors.RuntimeError('DS.find(resourceName, id[, forceRefresh]): ' + resourceName + ' is not a registered resource!'));
55+
deferred.reject(new errors.RuntimeError(errorPrefix + resourceName + ' is not a registered resource!'));
4256
} else if (!utils.isString(id) && !utils.isNumber(id)) {
43-
deferred.reject(new errors.IllegalArgumentError('DS.find(resourceName, id[, forceRefresh]): id: Must be a string or a number!', { id: { actual: typeof id, expected: 'string|number' } }));
44-
}
45-
46-
var _this = this;
57+
deferred.reject(new errors.IllegalArgumentError(errorPrefix + 'id: Must be a string or a number!', { id: { actual: typeof id, expected: 'string|number' } }));
58+
} else if (!utils.isObject(options)) {
59+
deferred.reject(new errors.IllegalArgumentError(errorPrefix + 'options: Must be an object!', { options: { actual: typeof options, expected: 'object' } }));
60+
} else {
61+
var _this = this;
4762

48-
try {
49-
var resource = store[resourceName];
63+
try {
64+
var resource = store[resourceName];
5065

51-
if (id in resource.index && !forceRefresh) {
52-
deferred.resolve(_this.get(resourceName, id));
53-
} else {
54-
GET(utils.makePath(resource.url, id), null).then(function (data) {
55-
try {
56-
_this.inject(resourceName, data);
57-
deferred.resolve(_this.get(resourceName, id));
58-
} catch (err) {
59-
deferred.reject(err);
60-
}
61-
}, deferred.reject);
66+
if (id in resource.index && !options.bypassCache) {
67+
deferred.resolve(_this.get(resourceName, id));
68+
} else {
69+
GET(utils.makePath(resource.url, id), null).then(function (data) {
70+
try {
71+
_this.inject(resourceName, data);
72+
deferred.resolve(_this.get(resourceName, id));
73+
} catch (err) {
74+
deferred.reject(err);
75+
}
76+
}, deferred.reject);
77+
}
78+
} catch (err) {
79+
if (!(err instanceof errors.UnhandledError)) {
80+
deferred.reject(new errors.UnhandledError(err));
81+
} else {
82+
deferred.reject(err);
83+
}
6284
}
63-
} catch (err) {
64-
deferred.reject(new errors.UnhandledError(err));
6585
}
6686

6787
return deferred.promise;

src/datastore/async_methods/findAll/index.js

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,12 @@ function processResults(data, resourceName, queryHash) {
3333
return temp;
3434
}
3535

36-
function _findAll(deferred, resourceName, params, forceRefresh) {
36+
function _findAll(deferred, resourceName, params, options) {
3737
var resource = store[resourceName];
3838

3939
var queryHash = utils.toJson(params);
4040

41-
if (forceRefresh) {
41+
if (options.bypassCache) {
4242
delete resource.completedQueries[queryHash];
4343
}
4444

@@ -57,7 +57,7 @@ function _findAll(deferred, resourceName, params, forceRefresh) {
5757
}, deferred.reject);
5858
}
5959
} else {
60-
deferred.resolve(this.filter(resourceName, params));
60+
deferred.resolve(this.filter(resourceName, params, options));
6161
}
6262
}
6363

@@ -66,51 +66,60 @@ function _findAll(deferred, resourceName, params, forceRefresh) {
6666
* @id DS.async_methods:findAll
6767
* @name findAll
6868
* @description
69-
* `findAll(resourceName[, params][, forceRefresh])`
70-
*
7169
* Asynchronously return the resource from the server filtered by the query. The results will be added to the data
7270
* store when it returns from the server.
7371
*
74-
* Example:
72+
* ## Signature:
73+
* ```js
74+
* DS.findAll(resourceName, params[, options])
75+
* ```
76+
*
77+
* ## Example:
7578
*
7679
* ```js
77-
* TODO: findAll(resourceName[, params][, forceRefresh]) example
80+
* TODO: findAll(resourceName, params[, options]) example
7881
* ```
7982
*
8083
* @param {string} resourceName The resource type, e.g. 'user', 'comment', etc.
81-
* @param {object=} params Parameter object that is serialized into the query string. Properties:
84+
* @param {object} params Parameter object that is serialized into the query string. Properties:
8285
*
8386
* - `{object=}` - `query` - The query object by which to filter items of the type specified by `resourceName`. Properties:
8487
* - `{object=}` - `where` - Where clause.
8588
* - `{number=}` - `limit` - Limit clause.
8689
* - `{skip=}` - `skip` - Skip clause.
90+
* - `{orderBy=}` - `orderBy` - OrderBy clause.
8791
*
88-
* @param {boolean=} forceRefresh Bypass the cache.
92+
* @param {object=} options Optional configuration. Properties:
93+
* - `{boolean=}` - `bypassCache` - Bypass the cache. Default: `false`.
94+
* - `{string=}` - `mergeStrategy` - If `findAll` is called, specify the merge strategy that should be used when the new
95+
* items are injected into the data store. Default `"mergeWithExisting"`.
8996
*
9097
* @returns {Promise} Promise produced by the `$q` service.
9198
*
92-
* ## ResolvesWith:
99+
* ## Resolves with:
93100
*
94101
* - `{array}` - `items` - The collection of items returned by the server.
95102
*
96-
* ## RejectsWith:
103+
* ## Rejects with:
97104
*
98-
* - `{IllegalArgumentError}` - `err` - Argument `params` must be an object.
99-
* - `{RuntimeError}` - `err` - Argument `resourceName` must refer to an already registered resource.
100-
* - `{UnhandledError}` - `err` - Thrown for any uncaught exception.
105+
* - `{IllegalArgumentError}`
106+
* - `{RuntimeError}`
107+
* - `{UnhandledError}`
101108
*/
102-
function findAll(resourceName, params, forceRefresh) {
109+
function findAll(resourceName, params, options) {
103110
var deferred = services.$q.defer();
104111

105-
params = params || {};
112+
options = options || {};
106113

107114
if (!store[resourceName]) {
108115
deferred.reject(new errors.RuntimeError('DS.findAll(resourceName[, params]): ' + resourceName + ' is not a registered resource!'));
109116
} else if (!utils.isObject(params)) {
110-
deferred.reject(new errors.IllegalArgumentError('DS.findAll(resourceName[, params]): params: Must be an object!', { params: { actual: typeof params, expected: 'object' } }));
117+
deferred.reject(new errors.IllegalArgumentError('DS.findAll(resourceName, params[, options]): params: Must be an object!', { params: { actual: typeof params, expected: 'object' } }));
118+
} else if (!utils.isObject(options)) {
119+
deferred.reject(new errors.IllegalArgumentError('DS.findAll(resourceName, params[, options]): options: Must be an object!', { options: { actual: typeof options, expected: 'object' } }));
111120
} else {
112121
try {
113-
_findAll.apply(this, [deferred, resourceName, params, forceRefresh]);
122+
_findAll.apply(this, [deferred, resourceName, params, options]);
114123
} catch (err) {
115124
deferred.reject(new errors.UnhandledError(err));
116125
}

src/datastore/async_methods/save/index.js

Lines changed: 50 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ var utils = require('utils'),
22
errors = require('errors'),
33
store = require('store'),
44
services = require('services'),
5-
PUT = require('../../HTTP').PUT;
5+
PUT = require('../../HTTP').PUT,
6+
errorPrefix = 'DS.save(resourceName, id[, options]): ';
67

7-
function _save(deferred, resource, id, attrs) {
8+
function _save(deferred, resource, id, options) {
89
var _this = this;
9-
PUT(utils.makePath(resource.url, id), attrs, null).then(function (data) {
10-
var saved = _this.inject(resource.name, data);
11-
resource.saved[saved[resource.idAttribute]] = utils.saveTimestamp(resource.saved[saved[resource.idAttribute]]);
10+
PUT(utils.makePath(resource.url, id), resource.index[id], null).then(function (data) {
11+
var saved = _this.inject(resource.name, data, options);
12+
resource.saved[id] = utils.updateTimestamp(resource.saved[id]);
1213
deferred.resolve(saved);
1314
}, deferred.reject);
1415
}
@@ -18,56 +19,72 @@ function _save(deferred, resource, id, attrs) {
1819
* @id DS.async_methods:save
1920
* @name save
2021
* @description
21-
* `save(resourceName, id)`
22+
* Save the item of the type specified by `resourceName` that has the primary key specified by `id`.
2223
*
23-
* save the item of the type specified by `resourceName` that has the primary key specified by `id`.
24+
* ## Signature:
25+
* ```js
26+
* DS.save(resourceName, id[, options])
27+
* ```
2428
*
25-
* Example:
29+
* ## Example:
2630
*
2731
* ```js
2832
* TODO: save(resourceName, id) example
2933
* ```
3034
*
3135
* @param {string} resourceName The resource type, e.g. 'user', 'comment', etc.
3236
* @param {string|number} id The primary key of the item to retrieve.
37+
* @param {object=} options Optional configuration. Properties:
38+
* - `{string=}` - `mergeStrategy` - When the updated item returns from the server, specify the merge strategy that
39+
* should be used when the updated item is injected into the data store. Default: `"mergeWithExisting"`.
40+
*
3341
* @returns {Promise} Promise produced by the `$q` service.
3442
*
35-
* ## ResolvesWith:
43+
* ## Resolves with:
3644
*
3745
* - `{object}` - `item` - A reference to the newly saved item.
3846
*
39-
* ## RejectsWith:
47+
* ## Rejects with:
4048
*
41-
* - `{IllegalArgumentError}` - `err` - Argument `id` must be a string or a number.
42-
* - `{RuntimeError}` - `err` - Argument `resourceName` must refer to an already registered resource.
43-
* - `{UnhandledError}` - `err` - Thrown for any uncaught exception.
49+
* - `{IllegalArgumentError}`
50+
* - `{RuntimeError}`
51+
* - `{UnhandledError}`
4452
*/
45-
function save(resourceName, id) {
53+
function save(resourceName, id, options) {
4654
var deferred = $q.defer();
55+
56+
options = options || {};
57+
4758
if (!store[resourceName]) {
48-
deferred.reject(new errors.RuntimeError('DS.save(resourceName, id, attrs): ' + resourceName + ' is not a registered resource!'));
59+
deferred.reject(new errors.RuntimeError(errorPrefix + resourceName + ' is not a registered resource!'));
4960
} else if (!utils.isString(id) && !utils.isNumber(id)) {
50-
deferred.reject(new errors.IllegalArgumentError('DS.save(resourceName, id, attrs): id: Must be a string or a number!', { id: { actual: typeof id, expected: 'string|number' } }));
51-
}
52-
53-
var _this = this;
61+
deferred.reject(new errors.IllegalArgumentError(errorPrefix + 'id: Must be a string or a number!', { id: { actual: typeof id, expected: 'string|number' } }));
62+
} else if (!utils.isObject(options)) {
63+
deferred.reject(new errors.IllegalArgumentError(errorPrefix + 'id: Must be an object!', { options: { actual: typeof options, expected: 'object' } }));
64+
} else {
65+
var _this = this;
5466

55-
try {
56-
var resource = store[resourceName];
67+
try {
68+
var resource = store[resourceName];
5769

58-
if (resource.validate) {
59-
resource.validate(resource.index[resource.idAttribute || 'id'], function (err) {
60-
if (err) {
61-
deferred.reject(err);
62-
} else {
63-
_save.call(_this, deferred, resource, id);
64-
}
65-
});
66-
} else {
67-
_save.call(_this, deferred, resource, id);
70+
if (resource.schema) {
71+
resource.schema.validate(resource.index[id], function (err) {
72+
if (err) {
73+
deferred.reject(err);
74+
} else {
75+
_save.call(_this, deferred, resource, id, options);
76+
}
77+
});
78+
} else {
79+
_save.call(_this, deferred, resource, id, options);
80+
}
81+
} catch (err) {
82+
if (!(err instanceof errors.UnhandledError)) {
83+
deferred.reject(new errors.UnhandledError(err));
84+
} else {
85+
deferred.reject(err);
86+
}
6887
}
69-
} catch (err) {
70-
deferred.reject(new errors.UnhandledError(err));
7188
}
7289

7390
return deferred.promise;

0 commit comments

Comments
 (0)