angularjs-rails-resource 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -27,319 +27,350 @@
27
27
  };
28
28
  });
29
29
 
30
- angular.module('rails').factory('railsResourceFactory', ['$http', '$q', 'railsUrlBuilder', 'railsSerializer', 'railsRootWrappingTransformer', 'railsRootWrappingInterceptor', 'RailsResourceInjector',
30
+ angular.module('rails').provider('railsResourceFactory', function () {
31
+ var defaultOptions = {
32
+ enableRootWrapping: true,
33
+ updateMethod: 'put',
34
+ httpConfig: {},
35
+ defaultParams: undefined
36
+ };
37
+
38
+ this.enableRootWrapping = function (value) {
39
+ defaultOptions.enableRootWrapping = value;
40
+ return this;
41
+ };
42
+
43
+ this.updateMethod = function (value) {
44
+ defaultOptions.updateMethod = value;
45
+ return this;
46
+ };
47
+
48
+ this.httpConfig = function (value) {
49
+ defaultOptions.httpConfig = value;
50
+ return this;
51
+ };
52
+
53
+ this.defaultParams = function (value) {
54
+ defaultOptions.defaultParams = value;
55
+ return this;
56
+ };
57
+
58
+ this.$get = ['$http', '$q', 'railsUrlBuilder', 'railsSerializer', 'railsRootWrappingTransformer', 'railsRootWrappingInterceptor', 'RailsResourceInjector',
31
59
  function ($http, $q, railsUrlBuilder, railsSerializer, railsRootWrappingTransformer, railsRootWrappingInterceptor, RailsResourceInjector) {
32
60
 
33
- function railsResourceFactory(config) {
34
- var transformers = config.requestTransformers,
35
- interceptors = config.responseInterceptors,
36
- afterInterceptors = config.afterResponseInterceptors;
61
+ function railsResourceFactory(config) {
62
+ var transformers = config.requestTransformers,
63
+ interceptors = config.responseInterceptors,
64
+ afterInterceptors = config.afterResponseInterceptors;
37
65
 
38
- function appendPath(url, path) {
39
- if (path) {
40
- if (path[0] !== '/') {
41
- url += '/';
66
+ function appendPath(url, path) {
67
+ if (path) {
68
+ if (path[0] !== '/') {
69
+ url += '/';
70
+ }
71
+
72
+ url += path;
42
73
  }
43
74
 
44
- url += path;
75
+ return url;
45
76
  }
46
77
 
47
- return url;
48
- }
78
+ function RailsResource(value) {
79
+ var instance = this;
80
+ if (value) {
81
+ var immediatePromise = function(data) {
82
+ return {
83
+ resource: RailsResource,
84
+ context: instance,
85
+ response: data,
86
+ then: function(callback) {
87
+ this.response = callback(this.response, this.resource, this.context);
88
+ return immediatePromise(this.response);
89
+ }
90
+ }
91
+ };
92
+
93
+ var data = RailsResource.callInterceptors(immediatePromise({data: value}), this).response.data;
94
+ angular.extend(this, data);
95
+ }
96
+ }
49
97
 
50
- function RailsResource(value) {
51
- var instance = this;
52
- if (value) {
53
- var immediatePromise = function(data) {
54
- return {
55
- resource: RailsResource,
56
- context: instance,
57
- response: data,
58
- then: function(callback) {
59
- this.response = callback(this.response, this.resource, this.context);
60
- return immediatePromise(this.response);
61
- }
62
- }
63
- };
98
+ RailsResource.setUrl = function(url) {
99
+ RailsResource.url = railsUrlBuilder(url);
100
+ };
101
+ RailsResource.setUrl(config.url);
102
+
103
+ RailsResource.enableRootWrapping = config.wrapData === undefined ? defaultOptions.enableRootWrapping : config.wrapData; // using undefined check because config.wrapData || true would be true when config.wrapData === false
104
+ RailsResource.httpConfig = config.httpConfig || defaultOptions.httpConfig;
105
+ RailsResource.httpConfig.headers = angular.extend({'Accept': 'application/json', 'Content-Type': 'application/json'}, RailsResource.httpConfig.headers || {});
106
+ RailsResource.defaultParams = config.defaultParams || defaultOptions.defaultParams;
107
+ RailsResource.updateMethod = (config.updateMethod || defaultOptions.updateMethod).toLowerCase();
108
+
109
+ RailsResource.requestTransformers = [];
110
+ RailsResource.responseInterceptors = [];
111
+ RailsResource.afterResponseInterceptors = [];
112
+ RailsResource.serializer = RailsResourceInjector.createService(config.serializer || railsSerializer());
113
+ RailsResource.rootName = RailsResource.serializer.underscore(config.name);
114
+ RailsResource.rootPluralName = RailsResource.serializer.underscore(config.pluralName || RailsResource.serializer.pluralize(config.name));
115
+
116
+ /**
117
+ * Add a callback to run on response and construction.
118
+ * @param fn(response data, constructor, context) - response data is either the resource instance returned or an array of resource instances,
119
+ * constructor is the resource class calling the function,
120
+ * context is the resource instance of the calling method (create, update, delete) or undefined if the method was a class method (get, query)
121
+ */
122
+ RailsResource.beforeResponse = function(fn) {
123
+ fn = RailsResourceInjector.getDependency(fn);
124
+ RailsResource.responseInterceptors.push(function(promise) {
125
+ return promise.then(function(response) {
126
+ fn(response.data, promise.resource, promise.context);
127
+ return response;
128
+ });
129
+ });
130
+ };
64
131
 
65
- var data = RailsResource.callInterceptors(immediatePromise({data: value}), this).response.data;
66
- angular.extend(this, data);
67
- }
68
- }
132
+ /**
133
+ * Add a callback to run after response has been processed. These callbacks are not called on object construction.
134
+ * @param fn(response data, constructor) - response data is either the resource instance returned or an array of resource instances and constructor is the resource class calling the function
135
+ */
136
+ RailsResource.afterResponse = function(fn) {
137
+ fn = RailsResourceInjector.getDependency(fn);
138
+ RailsResource.afterResponseInterceptors.push(function(promise) {
139
+ return promise.then(function(response) {
140
+ fn(response, promise.resource);
141
+ return response;
142
+ });
143
+ });
144
+ };
145
+
146
+ /**
147
+ * Adds a function to run after serializing the data to send to the server, but before root-wrapping it.
148
+ * @param fn (data, constructor) - data object is the serialized resource instance, and constructor the resource class calling the function
149
+ */
150
+ RailsResource.beforeRequest = function(fn) {
151
+ fn = RailsResourceInjector.getDependency(fn);
152
+ RailsResource.requestTransformers.push(function(data, resource) {
153
+ return fn(data, resource) || data;
154
+ });
155
+ };
69
156
 
70
- RailsResource.setUrl = function(url) {
71
- RailsResource.url = railsUrlBuilder(url);
72
- };
73
- RailsResource.setUrl(config.url);
74
-
75
- RailsResource.enableRootWrapping = config.wrapData === undefined ? true : config.wrapData;
76
- RailsResource.httpConfig = config.httpConfig || {};
77
- RailsResource.httpConfig.headers = angular.extend({'Accept': 'application/json', 'Content-Type': 'application/json'}, RailsResource.httpConfig.headers || {});
78
- RailsResource.requestTransformers = [];
79
- RailsResource.responseInterceptors = [];
80
- RailsResource.afterResponseInterceptors = [];
81
- RailsResource.defaultParams = config.defaultParams;
82
- RailsResource.serializer = RailsResourceInjector.createService(config.serializer || railsSerializer());
83
- RailsResource.rootName = RailsResource.serializer.underscore(config.name);
84
- RailsResource.rootPluralName = RailsResource.serializer.underscore(config.pluralName || RailsResource.serializer.pluralize(config.name));
85
-
86
- /**
87
- * Add a callback to run on response and construction.
88
- * @param fn(response data, constructor, context) - response data is either the resource instance returned or an array of resource instances,
89
- * constructor is the resource class calling the function,
90
- * context is the resource instance of the calling method (create, update, delete) or undefined if the method was a class method (get, query)
91
- */
92
- RailsResource.beforeResponse = function(fn) {
93
- fn = RailsResourceInjector.getDependency(fn);
94
- RailsResource.responseInterceptors.push(function(promise) {
95
- return promise.then(function(response) {
96
- fn(response.data, promise.resource, promise.context);
97
- return response;
157
+ // copied from $HttpProvider to support interceptors being dependency names or anonymous factory functions
158
+ angular.forEach(interceptors, function (interceptor) {
159
+ RailsResource.responseInterceptors.push(RailsResourceInjector.getDependency(interceptor));
98
160
  });
99
- });
100
- };
101
-
102
- /**
103
- * Add a callback to run after response has been processed. These callbacks are not called on object construction.
104
- * @param fn(response data, constructor) - response data is either the resource instance returned or an array of resource instances and constructor is the resource class calling the function
105
- */
106
- RailsResource.afterResponse = function(fn) {
107
- fn = RailsResourceInjector.getDependency(fn);
108
- RailsResource.afterResponseInterceptors.push(function(promise) {
109
- return promise.then(function(response) {
110
- fn(response, promise.resource);
111
- return response;
161
+
162
+ angular.forEach(afterInterceptors, function (interceptor) {
163
+ RailsResource.afterResponseInterceptors.push(RailsResourceInjector.getDependency(interceptor));
112
164
  });
113
- });
114
- };
115
-
116
- /**
117
- * Adds a function to run after serializing the data to send to the server, but before root-wrapping it.
118
- * @param fn (data, constructor) - data object is the serialized resource instance, and constructor the resource class calling the function
119
- */
120
- RailsResource.beforeRequest = function(fn) {
121
- fn = RailsResourceInjector.getDependency(fn);
122
- RailsResource.requestTransformers.push(function(data, resource) {
123
- return fn(data, resource) || data;
124
- });
125
- };
126
-
127
- // copied from $HttpProvider to support interceptors being dependency names or anonymous factory functions
128
- angular.forEach(interceptors, function (interceptor) {
129
- RailsResource.responseInterceptors.push(RailsResourceInjector.getDependency(interceptor));
130
- });
131
165
 
132
- angular.forEach(afterInterceptors, function (interceptor) {
133
- RailsResource.afterResponseInterceptors.push(RailsResourceInjector.getDependency(interceptor));
134
- });
166
+ angular.forEach(transformers, function (transformer) {
167
+ RailsResource.requestTransformers.push(RailsResourceInjector.getDependency(transformer));
168
+ });
135
169
 
136
- angular.forEach(transformers, function (transformer) {
137
- RailsResource.requestTransformers.push(RailsResourceInjector.getDependency(transformer));
138
- });
170
+ // transform data for request:
171
+ RailsResource.transformData = function (data) {
172
+ data = RailsResource.serializer.serialize(data);
139
173
 
140
- // transform data for request:
141
- RailsResource.transformData = function (data) {
142
- data = RailsResource.serializer.serialize(data);
174
+ // data is now serialized. call request transformers including beforeRequest
175
+ angular.forEach(RailsResource.requestTransformers, function (transformer) {
176
+ data = transformer(data, RailsResource);
177
+ });
143
178
 
144
- // data is now serialized. call request transformers including beforeRequest
145
- angular.forEach(RailsResource.requestTransformers, function (transformer) {
146
- data = transformer(data, RailsResource);
147
- });
148
179
 
180
+ if (RailsResource.enableRootWrapping) {
181
+ data = railsRootWrappingTransformer(data, RailsResource);
182
+ }
149
183
 
150
- if (RailsResource.enableRootWrapping) {
151
- data = railsRootWrappingTransformer(data, RailsResource);
152
- }
184
+ return data;
185
+ };
153
186
 
154
- return data;
155
- };
187
+ // transform data on response:
188
+ RailsResource.callInterceptors = function (promise, context) {
189
+ promise = promise.then(function (response) {
190
+ // store off the data in case something (like our root unwrapping) assigns data as a new object
191
+ response.originalData = response.data;
192
+ return response;
193
+ });
194
+
195
+ if (RailsResource.enableRootWrapping) {
196
+ promise.resource = RailsResource;
197
+ promise = railsRootWrappingInterceptor(promise);
198
+ }
156
199
 
157
- // transform data on response:
158
- RailsResource.callInterceptors = function (promise, context) {
159
- promise = promise.then(function (response) {
160
- // store off the data in case something (like our root unwrapping) assigns data as a new object
161
- response.originalData = response.data;
162
- return response;
163
- });
200
+ promise.then(function (response) {
201
+ response.data = RailsResource.serializer.deserialize(response.data, RailsResource);
202
+ return response;
203
+ });
164
204
 
165
- if (RailsResource.enableRootWrapping) {
166
- promise.resource = RailsResource;
167
- promise = railsRootWrappingInterceptor(promise);
168
- }
205
+ // data is now deserialized. call response interceptors including beforeResponse
206
+ angular.forEach(RailsResource.responseInterceptors, function (interceptor) {
207
+ promise.resource = RailsResource;
208
+ promise.context = context;
209
+ promise = interceptor(promise);
210
+ });
169
211
 
170
- promise.then(function (response) {
171
- response.data = RailsResource.serializer.deserialize(response.data, RailsResource);
172
- return response;
173
- });
212
+ return promise;
213
+ };
174
214
 
175
- // data is now deserialized. call response interceptors including beforeResponse
176
- angular.forEach(RailsResource.responseInterceptors, function (interceptor) {
177
- promise.resource = RailsResource;
178
- promise.context = context;
179
- promise = interceptor(promise);
180
- });
215
+ // transform data after response has been converted to a resource instance:
216
+ RailsResource.callAfterInterceptors = function (promise) {
217
+ // data is now deserialized. call response interceptors including afterResponse
218
+ angular.forEach(RailsResource.afterResponseInterceptors, function (interceptor) {
219
+ promise.resource = RailsResource;
220
+ promise = interceptor(promise);
221
+ });
181
222
 
182
- return promise;
183
- };
184
-
185
- // transform data after response has been converted to a resource instance:
186
- RailsResource.callAfterInterceptors = function (promise) {
187
- // data is now deserialized. call response interceptors including afterResponse
188
- angular.forEach(RailsResource.afterResponseInterceptors, function (interceptor) {
189
- promise.resource = RailsResource;
190
- promise = interceptor(promise);
191
- });
223
+ return promise;
224
+ };
192
225
 
193
- return promise;
194
- };
226
+ RailsResource.processResponse = function (promise) {
227
+ promise = RailsResource.callInterceptors(promise).then(function (response) {
228
+ return response.data;
229
+ });
195
230
 
196
- RailsResource.processResponse = function (promise) {
197
- promise = RailsResource.callInterceptors(promise).then(function (response) {
198
- return response.data;
199
- });
200
-
201
- return RailsResource.callAfterInterceptors(promise);
202
- };
231
+ return RailsResource.callAfterInterceptors(promise);
232
+ };
203
233
 
204
- RailsResource.getParameters = function (queryParams) {
205
- var params;
234
+ RailsResource.getParameters = function (queryParams) {
235
+ var params;
206
236
 
207
- if (RailsResource.defaultParams) {
208
- params = RailsResource.defaultParams;
209
- }
237
+ if (RailsResource.defaultParams) {
238
+ params = RailsResource.defaultParams;
239
+ }
210
240
 
211
- if (angular.isObject(queryParams)) {
212
- params = angular.extend(params || {}, queryParams);
213
- }
241
+ if (angular.isObject(queryParams)) {
242
+ params = angular.extend(params || {}, queryParams);
243
+ }
214
244
 
215
- return params;
216
- };
245
+ return params;
246
+ };
217
247
 
218
- RailsResource.getHttpConfig = function (queryParams) {
219
- var params = RailsResource.getParameters(queryParams);
248
+ RailsResource.getHttpConfig = function (queryParams) {
249
+ var params = RailsResource.getParameters(queryParams);
220
250
 
221
- if (params) {
222
- return angular.extend({params: params}, RailsResource.httpConfig);
223
- }
251
+ if (params) {
252
+ return angular.extend({params: params}, RailsResource.httpConfig);
253
+ }
224
254
 
225
- return angular.copy(RailsResource.httpConfig);
226
- };
227
-
228
- /**
229
- * Returns a URL from the given parameters. You can override this method on your resource definitions to provide
230
- * custom logic for building your URLs or you can utilize the parameterized url strings to substitute values in the
231
- * URL string.
232
- *
233
- * The parameters in the URL string follow the normal Angular binding expression using {{ and }} for the start/end symbols.
234
- *
235
- * If the context is a number and the URL string does not contain an id parameter then the number is appended
236
- * to the URL string.
237
- *
238
- * If the context is a number and the URL string does
239
- * @param context
240
- * @param path {string} (optional) An additional path to append to the URL
241
- * @return {string}
242
- */
243
- RailsResource.$url = RailsResource.resourceUrl = function (context, path) {
244
- if (!angular.isObject(context)) {
245
- context = {id: context};
246
- }
255
+ return angular.copy(RailsResource.httpConfig);
256
+ };
247
257
 
248
- return appendPath(RailsResource.url(context || {}), path);
249
- };
250
-
251
- RailsResource.$get = function (url, queryParams) {
252
- return RailsResource.processResponse($http.get(url, RailsResource.getHttpConfig(queryParams)));
253
- };
254
-
255
- RailsResource.query = function (queryParams, context) {
256
- return RailsResource.$get(RailsResource.resourceUrl(context), queryParams);
257
- };
258
-
259
- RailsResource.get = function (context, queryParams) {
260
- return RailsResource.$get(RailsResource.resourceUrl(context), queryParams);
261
- };
262
-
263
- /**
264
- * Returns the URL for this resource.
265
- *
266
- * @param path {string} (optional) An additional path to append to the URL
267
- * @returns {string} The URL for the resource
268
- */
269
- RailsResource.prototype.$url = function(path) {
270
- return appendPath(RailsResource.resourceUrl(this), path);
271
- };
272
-
273
- RailsResource.prototype.processResponse = function (promise) {
274
- promise = RailsResource.callInterceptors(promise, this);
275
-
276
- promise = promise.then(angular.bind(this, function (response) {
277
- // we may not have response data
278
- if (response.hasOwnProperty('data') && angular.isObject(response.data)) {
279
- angular.extend(this, response.data);
258
+ /**
259
+ * Returns a URL from the given parameters. You can override this method on your resource definitions to provide
260
+ * custom logic for building your URLs or you can utilize the parameterized url strings to substitute values in the
261
+ * URL string.
262
+ *
263
+ * The parameters in the URL string follow the normal Angular binding expression using {{ and }} for the start/end symbols.
264
+ *
265
+ * If the context is a number and the URL string does not contain an id parameter then the number is appended
266
+ * to the URL string.
267
+ *
268
+ * If the context is a number and the URL string does
269
+ * @param context
270
+ * @param path {string} (optional) An additional path to append to the URL
271
+ * @return {string}
272
+ */
273
+ RailsResource.$url = RailsResource.resourceUrl = function (context, path) {
274
+ if (!angular.isObject(context)) {
275
+ context = {id: context};
280
276
  }
281
277
 
282
- return this;
283
- }));
278
+ return appendPath(RailsResource.url(context || {}), path);
279
+ };
284
280
 
285
- return RailsResource.callAfterInterceptors(promise);
286
- };
281
+ RailsResource.$get = function (url, queryParams) {
282
+ return RailsResource.processResponse($http.get(url, RailsResource.getHttpConfig(queryParams)));
283
+ };
287
284
 
288
- angular.forEach(['post', 'put', 'patch'], function (method) {
289
- RailsResource['$' + method] = function (url, data) {
290
- var config;
291
- // clone so we can manipulate w/o modifying the actual instance
292
- data = RailsResource.transformData(angular.copy(data, {}));
293
- config = angular.extend({method: method, url: url, data: data}, RailsResource.getHttpConfig());
294
- return RailsResource.processResponse($http(config));
285
+ RailsResource.query = function (queryParams, context) {
286
+ return RailsResource.$get(RailsResource.resourceUrl(context), queryParams);
295
287
  };
296
288
 
297
- RailsResource.prototype['$' + method] = function (url) {
298
- var data, config;
299
- // clone so we can manipulate w/o modifying the actual instance
300
- data = RailsResource.transformData(angular.copy(this, {}));
301
- config = angular.extend({method: method, url: url, data: data}, RailsResource.getHttpConfig());
302
- return this.processResponse($http(config));
289
+ RailsResource.get = function (context, queryParams) {
290
+ return RailsResource.$get(RailsResource.resourceUrl(context), queryParams);
291
+ };
303
292
 
293
+ /**
294
+ * Returns the URL for this resource.
295
+ *
296
+ * @param path {string} (optional) An additional path to append to the URL
297
+ * @returns {string} The URL for the resource
298
+ */
299
+ RailsResource.prototype.$url = function(path) {
300
+ return appendPath(RailsResource.resourceUrl(this), path);
304
301
  };
305
- });
306
302
 
307
- RailsResource.prototype.create = function () {
308
- return this.$post(this.$url(), this);
309
- };
303
+ RailsResource.prototype.processResponse = function (promise) {
304
+ promise = RailsResource.callInterceptors(promise, this);
310
305
 
311
- RailsResource.prototype.update = function () {
312
- return this.$put(this.$url(), this);
313
- };
306
+ promise = promise.then(angular.bind(this, function (response) {
307
+ // we may not have response data
308
+ if (response.hasOwnProperty('data') && angular.isObject(response.data)) {
309
+ angular.extend(this, response.data);
310
+ }
314
311
 
315
- RailsResource.prototype.isNew = function () {
316
- return this.id == null;
317
- }
312
+ return this;
313
+ }));
318
314
 
319
- RailsResource.prototype.save = function () {
320
- if (this.isNew()) {
321
- return this.create();
322
- } else {
323
- return this.update();
315
+ return RailsResource.callAfterInterceptors(promise);
316
+ };
317
+
318
+ angular.forEach(['post', 'put', 'patch'], function (method) {
319
+ RailsResource['$' + method] = function (url, data) {
320
+ var config;
321
+ // clone so we can manipulate w/o modifying the actual instance
322
+ data = RailsResource.transformData(angular.copy(data, {}));
323
+ config = angular.extend({method: method, url: url, data: data}, RailsResource.getHttpConfig());
324
+ return RailsResource.processResponse($http(config));
325
+ };
326
+
327
+ RailsResource.prototype['$' + method] = function (url) {
328
+ var data, config;
329
+ // clone so we can manipulate w/o modifying the actual instance
330
+ data = RailsResource.transformData(angular.copy(this, {}));
331
+ config = angular.extend({method: method, url: url, data: data}, RailsResource.getHttpConfig());
332
+ return this.processResponse($http(config));
333
+
334
+ };
335
+ });
336
+
337
+ RailsResource.prototype.create = function () {
338
+ return this.$post(this.$url(), this);
339
+ };
340
+
341
+ RailsResource.prototype.update = function () {
342
+ return this['$' + RailsResource.updateMethod](this.$url(), this);
343
+ };
344
+
345
+ RailsResource.prototype.isNew = function () {
346
+ return this.id == null;
347
+ }
348
+
349
+ RailsResource.prototype.save = function () {
350
+ if (this.isNew()) {
351
+ return this.create();
352
+ } else {
353
+ return this.update();
354
+ }
324
355
  }
325
- }
326
356
 
327
- RailsResource['$delete'] = function (url) {
328
- return RailsResource.processResponse($http['delete'](url, RailsResource.getHttpConfig()));
329
- };
357
+ RailsResource['$delete'] = function (url) {
358
+ return RailsResource.processResponse($http['delete'](url, RailsResource.getHttpConfig()));
359
+ };
330
360
 
331
- RailsResource.prototype['$delete'] = function (url) {
332
- return this.processResponse($http['delete'](url, RailsResource.getHttpConfig()));
333
- };
361
+ RailsResource.prototype['$delete'] = function (url) {
362
+ return this.processResponse($http['delete'](url, RailsResource.getHttpConfig()));
363
+ };
334
364
 
335
- //using ['delete'] instead of .delete for IE7/8 compatibility
336
- RailsResource.prototype.remove = RailsResource.prototype['delete'] = function () {
337
- return this.$delete(this.$url());
338
- };
365
+ //using ['delete'] instead of .delete for IE7/8 compatibility
366
+ RailsResource.prototype.remove = RailsResource.prototype['delete'] = function () {
367
+ return this.$delete(this.$url());
368
+ };
339
369
 
340
- return RailsResource;
341
- }
370
+ return RailsResource;
371
+ }
342
372
 
343
- return railsResourceFactory;
344
- }]);
373
+ return railsResourceFactory;
374
+ }];
375
+ });
345
376
  }());