angularjs-rails 1.6.8 → 1.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +6 -1
- data/lib/angularjs-rails/version.rb +1 -1
- data/vendor/assets/javascripts/angular-animate.js +242 -128
- data/vendor/assets/javascripts/angular-aria.js +35 -10
- data/vendor/assets/javascripts/angular-cookies.js +9 -82
- data/vendor/assets/javascripts/angular-loader.js +46 -17
- data/vendor/assets/javascripts/angular-message-format.js +10 -10
- data/vendor/assets/javascripts/angular-messages.js +146 -58
- data/vendor/assets/javascripts/angular-mocks.js +613 -335
- data/vendor/assets/javascripts/angular-parse-ext.js +11 -5
- data/vendor/assets/javascripts/angular-resource.js +234 -180
- data/vendor/assets/javascripts/angular-route.js +99 -57
- data/vendor/assets/javascripts/angular-sanitize.js +132 -20
- data/vendor/assets/javascripts/angular-touch.js +27 -403
- data/vendor/assets/javascripts/angular.js +3796 -1555
- metadata +2 -3
- data/vendor/assets/javascripts/angular-scenario.js +0 -46603
@@ -1,6 +1,6 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.
|
3
|
-
* (c) 2010-
|
2
|
+
* @license AngularJS v1.8.0
|
3
|
+
* (c) 2010-2020 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
6
6
|
(function(window, angular) {'use strict';
|
@@ -1229,15 +1229,21 @@ function IDC_Y(cp) {
|
|
1229
1229
|
* @ngdoc module
|
1230
1230
|
* @name ngParseExt
|
1231
1231
|
* @packageName angular-parse-ext
|
1232
|
+
*
|
1232
1233
|
* @description
|
1233
1234
|
*
|
1234
1235
|
* The `ngParseExt` module provides functionality to allow Unicode characters in
|
1235
|
-
* identifiers inside
|
1236
|
+
* identifiers inside AngularJS expressions.
|
1236
1237
|
*
|
1237
1238
|
* This module allows the usage of any identifier that follows ES6 identifier naming convention
|
1238
|
-
* to be used as an identifier in an
|
1239
|
+
* to be used as an identifier in an AngularJS expression. ES6 delegates some of the identifier
|
1239
1240
|
* rules definition to Unicode, this module uses ES6 and Unicode 8.0 identifiers convention.
|
1240
1241
|
*
|
1242
|
+
* <div class="alert alert-warning">
|
1243
|
+
* You cannot use Unicode characters for variable names in the {@link ngRepeat} or {@link ngOptions}
|
1244
|
+
* expressions (e.g. `ng-repeat="f in поля"`), because even with `ngParseExt` included, these
|
1245
|
+
* special expressions are not parsed by the {@link $parse} service.
|
1246
|
+
* </div>
|
1241
1247
|
*/
|
1242
1248
|
|
1243
1249
|
/* global angularParseExtModule: true,
|
@@ -1263,7 +1269,7 @@ angular.module('ngParseExt', [])
|
|
1263
1269
|
.config(['$parseProvider', function($parseProvider) {
|
1264
1270
|
$parseProvider.setIdentifierFns(isValidIdentifierStart, isValidIdentifierContinue);
|
1265
1271
|
}])
|
1266
|
-
.info({ angularVersion: '1.
|
1272
|
+
.info({ angularVersion: '1.8.0' });
|
1267
1273
|
|
1268
1274
|
|
1269
1275
|
})(window, window.angular);
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.
|
3
|
-
* (c) 2010-
|
2
|
+
* @license AngularJS v1.8.0
|
3
|
+
* (c) 2010-2020 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
6
6
|
(function(window, angular) {'use strict';
|
@@ -115,13 +115,13 @@ function shallowClearAndCopy(src, dst) {
|
|
115
115
|
*
|
116
116
|
* @param {Object=} paramDefaults Default values for `url` parameters. These can be overridden in
|
117
117
|
* `actions` methods. If a parameter value is a function, it will be called every time
|
118
|
-
* a param value needs to be obtained for a request (unless the param was overridden). The
|
119
|
-
* will be passed the current data value as an argument.
|
118
|
+
* a param value needs to be obtained for a request (unless the param was overridden). The
|
119
|
+
* function will be passed the current data value as an argument.
|
120
120
|
*
|
121
121
|
* Each key value in the parameter object is first bound to url template if present and then any
|
122
122
|
* excess keys are appended to the url search query after the `?`.
|
123
123
|
*
|
124
|
-
* Given a template `/path/:verb` and parameter `{verb:'greet', salutation:'Hello'}` results in
|
124
|
+
* Given a template `/path/:verb` and parameter `{verb: 'greet', salutation: 'Hello'}` results in
|
125
125
|
* URL `/path/greet?salutation=Hello`.
|
126
126
|
*
|
127
127
|
* If the parameter value is prefixed with `@`, then the value for that parameter will be
|
@@ -130,7 +130,7 @@ function shallowClearAndCopy(src, dst) {
|
|
130
130
|
* For example, if the `defaultParam` object is `{someParam: '@someProp'}` then the value of
|
131
131
|
* `someParam` will be `data.someProp`.
|
132
132
|
* Note that the parameter will be ignored, when calling a "GET" action method (i.e. an action
|
133
|
-
* method that does not accept a request body)
|
133
|
+
* method that does not accept a request body).
|
134
134
|
*
|
135
135
|
* @param {Object.<Object>=} actions Hash with declaration of custom actions that will be available
|
136
136
|
* in addition to the default set of resource actions (see below). If a custom action has the same
|
@@ -139,9 +139,11 @@ function shallowClearAndCopy(src, dst) {
|
|
139
139
|
*
|
140
140
|
* The declaration should be created in the format of {@link ng.$http#usage $http.config}:
|
141
141
|
*
|
142
|
-
* {
|
143
|
-
*
|
144
|
-
*
|
142
|
+
* {
|
143
|
+
* action1: {method:?, params:?, isArray:?, headers:?, ...},
|
144
|
+
* action2: {method:?, params:?, isArray:?, headers:?, ...},
|
145
|
+
* ...
|
146
|
+
* }
|
145
147
|
*
|
146
148
|
* Where:
|
147
149
|
*
|
@@ -153,54 +155,58 @@ function shallowClearAndCopy(src, dst) {
|
|
153
155
|
* the parameter value is a function, it will be called every time when a param value needs to
|
154
156
|
* be obtained for a request (unless the param was overridden). The function will be passed the
|
155
157
|
* current data value as an argument.
|
156
|
-
* - **`url`** – {string} –
|
158
|
+
* - **`url`** – {string} – Action specific `url` override. The url templating is supported just
|
157
159
|
* like for the resource-level urls.
|
158
160
|
* - **`isArray`** – {boolean=} – If true then the returned object for this action is an array,
|
159
161
|
* see `returns` section.
|
160
162
|
* - **`transformRequest`** –
|
161
163
|
* `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
|
162
|
-
*
|
164
|
+
* Transform function or an array of such functions. The transform function takes the http
|
163
165
|
* request body and headers and returns its transformed (typically serialized) version.
|
164
166
|
* By default, transformRequest will contain one function that checks if the request data is
|
165
167
|
* an object and serializes it using `angular.toJson`. To prevent this behavior, set
|
166
168
|
* `transformRequest` to an empty array: `transformRequest: []`
|
167
169
|
* - **`transformResponse`** –
|
168
170
|
* `{function(data, headersGetter, status)|Array.<function(data, headersGetter, status)>}` –
|
169
|
-
*
|
171
|
+
* Transform function or an array of such functions. The transform function takes the HTTP
|
170
172
|
* response body, headers and status and returns its transformed (typically deserialized)
|
171
173
|
* version.
|
172
174
|
* By default, transformResponse will contain one function that checks if the response looks
|
173
175
|
* like a JSON string and deserializes it using `angular.fromJson`. To prevent this behavior,
|
174
176
|
* set `transformResponse` to an empty array: `transformResponse: []`
|
175
|
-
* - **`cache`** – `{boolean|Cache}` –
|
176
|
-
*
|
177
|
-
* {@link
|
178
|
-
*
|
179
|
-
* - **`timeout`** – `{number}` – timeout in milliseconds.<br />
|
177
|
+
* - **`cache`** – `{boolean|Cache}` – A boolean value or object created with
|
178
|
+
* {@link ng.$cacheFactory `$cacheFactory`} to enable or disable caching of the HTTP response.
|
179
|
+
* See {@link $http#caching $http Caching} for more information.
|
180
|
+
* - **`timeout`** – `{number}` – Timeout in milliseconds.<br />
|
180
181
|
* **Note:** In contrast to {@link ng.$http#usage $http.config}, {@link ng.$q promises} are
|
181
|
-
* **not** supported in
|
182
|
+
* **not** supported in `$resource`, because the same value would be used for multiple requests.
|
182
183
|
* If you are looking for a way to cancel requests, you should use the `cancellable` option.
|
183
|
-
* - **`cancellable`** – `{boolean}` –
|
184
|
-
*
|
185
|
-
*
|
186
|
-
*
|
187
|
-
* - **`withCredentials`**
|
184
|
+
* - **`cancellable`** – `{boolean}` – If true, the request made by a "non-instance" call will be
|
185
|
+
* cancelled (if not already completed) by calling `$cancelRequest()` on the call's return
|
186
|
+
* value. Calling `$cancelRequest()` for a non-cancellable or an already completed/cancelled
|
187
|
+
* request will have no effect.
|
188
|
+
* - **`withCredentials`** – `{boolean}` – Whether to set the `withCredentials` flag on the
|
188
189
|
* XHR object. See
|
189
|
-
* [
|
190
|
+
* [XMLHttpRequest.withCredentials](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials)
|
190
191
|
* for more information.
|
191
|
-
* - **`responseType`**
|
192
|
-
* [
|
193
|
-
* - **`interceptor`**
|
194
|
-
* `
|
195
|
-
*
|
196
|
-
*
|
197
|
-
*
|
192
|
+
* - **`responseType`** – `{string}` – See
|
193
|
+
* [XMLHttpRequest.responseType](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseType).
|
194
|
+
* - **`interceptor`** – `{Object=}` – The interceptor object has four optional methods -
|
195
|
+
* `request`, `requestError`, `response`, and `responseError`. See
|
196
|
+
* {@link ng.$http#interceptors $http interceptors} for details. Note that
|
197
|
+
* `request`/`requestError` interceptors are applied before calling `$http`, thus before any
|
198
|
+
* global `$http` interceptors. Also, rejecting or throwing an error inside the `request`
|
199
|
+
* interceptor will result in calling the `responseError` interceptor.
|
200
|
+
* The resource instance or collection is available on the `resource` property of the
|
201
|
+
* `http response` object passed to `response`/`responseError` interceptors.
|
198
202
|
* Keep in mind that the associated promise will be resolved with the value returned by the
|
199
|
-
* response
|
200
|
-
*
|
201
|
-
*
|
202
|
-
*
|
203
|
-
*
|
203
|
+
* response interceptors. Make sure you return an appropriate value and not the `response`
|
204
|
+
* object passed as input. For reference, the default `response` interceptor (which gets applied
|
205
|
+
* if you don't specify a custom one) returns `response.resource`.<br />
|
206
|
+
* See {@link ngResource.$resource#using-interceptors below} for an example of using
|
207
|
+
* interceptors in `$resource`.
|
208
|
+
* - **`hasBody`** – `{boolean}` – If true, then the request will have a body.
|
209
|
+
* If not specified, then only POST, PUT and PATCH requests will have a body. *
|
204
210
|
* @param {Object} options Hash with custom settings that should extend the
|
205
211
|
* default `$resourceProvider` behavior. The supported options are:
|
206
212
|
*
|
@@ -213,27 +219,29 @@ function shallowClearAndCopy(src, dst) {
|
|
213
219
|
* @returns {Object} A resource "class" object with methods for the default set of resource actions
|
214
220
|
* optionally extended with custom `actions`. The default set contains these actions:
|
215
221
|
* ```js
|
216
|
-
* {
|
217
|
-
* '
|
218
|
-
* '
|
219
|
-
* '
|
220
|
-
* '
|
222
|
+
* {
|
223
|
+
* 'get': {method: 'GET'},
|
224
|
+
* 'save': {method: 'POST'},
|
225
|
+
* 'query': {method: 'GET', isArray: true},
|
226
|
+
* 'remove': {method: 'DELETE'},
|
227
|
+
* 'delete': {method: 'DELETE'}
|
228
|
+
* }
|
221
229
|
* ```
|
222
230
|
*
|
223
|
-
* Calling these methods invoke
|
224
|
-
*
|
225
|
-
*
|
226
|
-
*
|
227
|
-
*
|
231
|
+
* Calling these methods invoke {@link ng.$http} with the specified http method, destination and
|
232
|
+
* parameters. When the data is returned from the server then the object is an instance of the
|
233
|
+
* resource class. The actions `save`, `remove` and `delete` are available on it as methods with
|
234
|
+
* the `$` prefix. This allows you to easily perform CRUD operations (create, read, update,
|
235
|
+
* delete) on server-side data like this:
|
228
236
|
* ```js
|
229
|
-
* var User = $resource('/user/:userId', {userId:'@id'});
|
230
|
-
*
|
237
|
+
* var User = $resource('/user/:userId', {userId: '@id'});
|
238
|
+
* User.get({userId: 123}).$promise.then(function(user) {
|
231
239
|
* user.abc = true;
|
232
240
|
* user.$save();
|
233
241
|
* });
|
234
242
|
* ```
|
235
243
|
*
|
236
|
-
* It is important to realize that invoking a
|
244
|
+
* It is important to realize that invoking a `$resource` object method immediately returns an
|
237
245
|
* empty reference (object or array depending on `isArray`). Once the data is returned from the
|
238
246
|
* server the existing reference is populated with the actual data. This is a useful trick since
|
239
247
|
* usually the resource is assigned to a model which is then rendered by the view. Having an empty
|
@@ -256,30 +264,31 @@ function shallowClearAndCopy(src, dst) {
|
|
256
264
|
*
|
257
265
|
*
|
258
266
|
* Success callback is called with (value (Object|Array), responseHeaders (Function),
|
259
|
-
* status (number), statusText (string)) arguments, where
|
267
|
+
* status (number), statusText (string)) arguments, where `value` is the populated resource
|
260
268
|
* instance or collection object. The error callback is called with (httpResponse) argument.
|
261
269
|
*
|
262
|
-
* Class actions return empty instance (with additional properties below).
|
263
|
-
* Instance actions return promise
|
270
|
+
* Class actions return an empty instance (with the additional properties listed below).
|
271
|
+
* Instance actions return a promise for the operation.
|
264
272
|
*
|
265
273
|
* The Resource instances and collections have these additional properties:
|
266
274
|
*
|
267
|
-
* - `$promise`:
|
275
|
+
* - `$promise`: The {@link ng.$q promise} of the original server interaction that created this
|
268
276
|
* instance or collection.
|
269
277
|
*
|
270
278
|
* On success, the promise is resolved with the same resource instance or collection object,
|
271
|
-
* updated with data from server. This makes it easy to use in
|
272
|
-
* {@link ngRoute.$routeProvider resolve section of
|
279
|
+
* updated with data from server. This makes it easy to use in the
|
280
|
+
* {@link ngRoute.$routeProvider `resolve` section of `$routeProvider.when()`} to defer view
|
273
281
|
* rendering until the resource(s) are loaded.
|
274
282
|
*
|
275
283
|
* On failure, the promise is rejected with the {@link ng.$http http response} object.
|
276
284
|
*
|
277
285
|
* If an interceptor object was provided, the promise will instead be resolved with the value
|
278
|
-
* returned by the interceptor.
|
286
|
+
* returned by the response interceptor (on success) or responceError interceptor (on failure).
|
279
287
|
*
|
280
288
|
* - `$resolved`: `true` after first server interaction is completed (either with success or
|
281
289
|
* rejection), `false` before that. Knowing if the Resource has been resolved is useful in
|
282
|
-
* data-binding.
|
290
|
+
* data-binding. If there is a response/responseError interceptor and it returns a promise,
|
291
|
+
* `$resolved` will wait for that too.
|
283
292
|
*
|
284
293
|
* The Resource instances and collections have these additional methods:
|
285
294
|
*
|
@@ -290,127 +299,134 @@ function shallowClearAndCopy(src, dst) {
|
|
290
299
|
*
|
291
300
|
* - `toJSON`: It returns a simple object without any of the extra properties added as part of
|
292
301
|
* the Resource API. This object can be serialized through {@link angular.toJson} safely
|
293
|
-
* without attaching
|
302
|
+
* without attaching AngularJS-specific fields. Notice that `JSON.stringify` (and
|
294
303
|
* `angular.toJson`) automatically use this method when serializing a Resource instance
|
295
304
|
* (see [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#toJSON%28%29_behavior)).
|
296
305
|
*
|
297
306
|
* @example
|
298
307
|
*
|
299
|
-
* ###
|
308
|
+
* ### Basic usage
|
300
309
|
*
|
301
|
-
|
302
|
-
// Define CreditCard class
|
303
|
-
var CreditCard = $resource('/
|
304
|
-
|
305
|
-
|
306
|
-
|
310
|
+
```js
|
311
|
+
// Define a CreditCard class
|
312
|
+
var CreditCard = $resource('/users/:userId/cards/:cardId',
|
313
|
+
{userId: 123, cardId: '@id'}, {
|
314
|
+
charge: {method: 'POST', params: {charge: true}}
|
315
|
+
});
|
307
316
|
|
308
317
|
// We can retrieve a collection from the server
|
309
|
-
var cards = CreditCard.query(
|
310
|
-
|
311
|
-
|
318
|
+
var cards = CreditCard.query();
|
319
|
+
// GET: /users/123/cards
|
320
|
+
// server returns: [{id: 456, number: '1234', name: 'Smith'}]
|
312
321
|
|
322
|
+
// Wait for the request to complete
|
323
|
+
cards.$promise.then(function() {
|
313
324
|
var card = cards[0];
|
314
|
-
|
325
|
+
|
326
|
+
// Each item is an instance of CreditCard
|
315
327
|
expect(card instanceof CreditCard).toEqual(true);
|
316
|
-
|
317
|
-
//
|
328
|
+
|
329
|
+
// Non-GET methods are mapped onto the instances
|
330
|
+
card.name = 'J. Smith';
|
318
331
|
card.$save();
|
319
|
-
|
320
|
-
|
332
|
+
// POST: /users/123/cards/456 {id: 456, number: '1234', name: 'J. Smith'}
|
333
|
+
// server returns: {id: 456, number: '1234', name: 'J. Smith'}
|
321
334
|
|
322
|
-
//
|
323
|
-
card.$charge({amount:9.99});
|
324
|
-
|
335
|
+
// Our custom method is mapped as well (since it uses POST)
|
336
|
+
card.$charge({amount: 9.99});
|
337
|
+
// POST: /users/123/cards/456?amount=9.99&charge=true {id: 456, number: '1234', name: 'J. Smith'}
|
325
338
|
});
|
326
339
|
|
327
|
-
//
|
328
|
-
var newCard = new CreditCard({number:'0123'});
|
329
|
-
newCard.name =
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
340
|
+
// We can create an instance as well
|
341
|
+
var newCard = new CreditCard({number: '0123'});
|
342
|
+
newCard.name = 'Mike Smith';
|
343
|
+
|
344
|
+
var savePromise = newCard.$save();
|
345
|
+
// POST: /users/123/cards {number: '0123', name: 'Mike Smith'}
|
346
|
+
// server returns: {id: 789, number: '0123', name: 'Mike Smith'}
|
347
|
+
|
348
|
+
savePromise.then(function() {
|
349
|
+
// Once the promise is resolved, the created instance
|
350
|
+
// is populated with the data returned by the server
|
351
|
+
expect(newCard.id).toEqual(789);
|
352
|
+
});
|
353
|
+
```
|
335
354
|
*
|
336
|
-
* The object returned from
|
337
|
-
* for each action in the definition.
|
355
|
+
* The object returned from a call to `$resource` is a resource "class" which has one "static"
|
356
|
+
* method for each action in the definition.
|
338
357
|
*
|
339
|
-
* Calling these methods
|
340
|
-
* `headers`.
|
358
|
+
* Calling these methods invokes `$http` on the `url` template with the given HTTP `method`,
|
359
|
+
* `params` and `headers`.
|
341
360
|
*
|
342
361
|
* @example
|
343
362
|
*
|
344
|
-
* ###
|
363
|
+
* ### Accessing the response
|
345
364
|
*
|
346
365
|
* When the data is returned from the server then the object is an instance of the resource type and
|
347
366
|
* all of the non-GET methods are available with `$` prefix. This allows you to easily support CRUD
|
348
367
|
* operations (create, read, update, delete) on server-side data.
|
349
|
-
|
368
|
+
*
|
350
369
|
```js
|
351
|
-
var User = $resource('/
|
352
|
-
User.get({userId:123}
|
370
|
+
var User = $resource('/users/:userId', {userId: '@id'});
|
371
|
+
User.get({userId: 123}).$promise.then(function(user) {
|
353
372
|
user.abc = true;
|
354
373
|
user.$save();
|
355
374
|
});
|
356
375
|
```
|
357
376
|
*
|
358
|
-
* It's worth noting that the success callback for `get`, `query` and other methods gets
|
359
|
-
*
|
360
|
-
*
|
377
|
+
* It's worth noting that the success callback for `get`, `query` and other methods gets called with
|
378
|
+
* the resource instance (populated with the data that came from the server) as well as an `$http`
|
379
|
+
* header getter function, the HTTP status code and the response status text. So one could rewrite
|
380
|
+
* the above example and get access to HTTP headers as follows:
|
361
381
|
*
|
362
382
|
```js
|
363
|
-
var User = $resource('/
|
364
|
-
User.get({userId:123}, function(user, getResponseHeaders){
|
383
|
+
var User = $resource('/users/:userId', {userId: '@id'});
|
384
|
+
User.get({userId: 123}, function(user, getResponseHeaders) {
|
365
385
|
user.abc = true;
|
366
386
|
user.$save(function(user, putResponseHeaders) {
|
367
|
-
//user => saved
|
368
|
-
//putResponseHeaders =>
|
387
|
+
// `user` => saved `User` object
|
388
|
+
// `putResponseHeaders` => `$http` header getter
|
369
389
|
});
|
370
390
|
});
|
371
391
|
```
|
372
392
|
*
|
373
|
-
* You can also access the raw `$http` promise via the `$promise` property on the object returned
|
374
|
-
*
|
375
|
-
```
|
376
|
-
var User = $resource('/user/:userId', {userId:'@id'});
|
377
|
-
User.get({userId:123})
|
378
|
-
.$promise.then(function(user) {
|
379
|
-
$scope.user = user;
|
380
|
-
});
|
381
|
-
```
|
382
|
-
*
|
383
393
|
* @example
|
384
394
|
*
|
385
|
-
* ### Creating
|
395
|
+
* ### Creating custom actions
|
386
396
|
*
|
387
|
-
* In this example we create a custom method on our resource to make a PUT request
|
388
|
-
*
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
397
|
+
* In this example we create a custom method on our resource to make a PUT request:
|
398
|
+
*
|
399
|
+
```js
|
400
|
+
var app = angular.module('app', ['ngResource']);
|
401
|
+
|
402
|
+
// Some APIs expect a PUT request in the format URL/object/ID
|
403
|
+
// Here we are creating an 'update' method
|
404
|
+
app.factory('Notes', ['$resource', function($resource) {
|
405
|
+
return $resource('/notes/:id', {id: '@id'}, {
|
406
|
+
update: {method: 'PUT'}
|
407
|
+
});
|
408
|
+
}]);
|
409
|
+
|
410
|
+
// In our controller we get the ID from the URL using `$location`
|
411
|
+
app.controller('NotesCtrl', ['$location', 'Notes', function($location, Notes) {
|
412
|
+
// First, retrieve the corresponding `Note` object from the server
|
413
|
+
// (Assuming a URL of the form `.../notes?id=XYZ`)
|
414
|
+
var noteId = $location.search().id;
|
415
|
+
var note = Notes.get({id: noteId});
|
416
|
+
|
417
|
+
note.$promise.then(function() {
|
418
|
+
note.content = 'Hello, world!';
|
419
|
+
|
420
|
+
// Now call `update` to save the changes on the server
|
421
|
+
Notes.update(note);
|
422
|
+
// This will PUT /notes/ID with the note object as the request payload
|
423
|
+
|
424
|
+
// Since `update` is a non-GET method, it will also be available on the instance
|
425
|
+
// (prefixed with `$`), so we could replace the `Note.update()` call with:
|
426
|
+
//note.$update();
|
427
|
+
});
|
428
|
+
}]);
|
429
|
+
```
|
414
430
|
*
|
415
431
|
* @example
|
416
432
|
*
|
@@ -421,7 +437,7 @@ function shallowClearAndCopy(src, dst) {
|
|
421
437
|
*
|
422
438
|
```js
|
423
439
|
// ...defining the `Hotel` resource...
|
424
|
-
var Hotel = $resource('/api/
|
440
|
+
var Hotel = $resource('/api/hotels/:id', {id: '@id'}, {
|
425
441
|
// Let's make the `query()` method cancellable
|
426
442
|
query: {method: 'get', isArray: true, cancellable: true}
|
427
443
|
});
|
@@ -431,17 +447,57 @@ function shallowClearAndCopy(src, dst) {
|
|
431
447
|
this.onDestinationChanged = function onDestinationChanged(destination) {
|
432
448
|
// We don't care about any pending request for hotels
|
433
449
|
// in a different destination any more
|
434
|
-
this.availableHotels
|
450
|
+
if (this.availableHotels) {
|
451
|
+
this.availableHotels.$cancelRequest();
|
452
|
+
}
|
435
453
|
|
436
|
-
// Let's query for hotels in
|
437
|
-
// (calls: /api/
|
454
|
+
// Let's query for hotels in `destination`
|
455
|
+
// (calls: /api/hotels?location=<destination>)
|
438
456
|
this.availableHotels = Hotel.query({location: destination});
|
439
457
|
};
|
440
458
|
```
|
441
459
|
*
|
460
|
+
* @example
|
461
|
+
*
|
462
|
+
* ### Using interceptors
|
463
|
+
*
|
464
|
+
* You can use interceptors to transform the request or response, perform additional operations, and
|
465
|
+
* modify the returned instance/collection. The following example, uses `request` and `response`
|
466
|
+
* interceptors to augment the returned instance with additional info:
|
467
|
+
*
|
468
|
+
```js
|
469
|
+
var Thing = $resource('/api/things/:id', {id: '@id'}, {
|
470
|
+
save: {
|
471
|
+
method: 'POST',
|
472
|
+
interceptor: {
|
473
|
+
request: function(config) {
|
474
|
+
// Before the request is sent out, store a timestamp on the request config
|
475
|
+
config.requestTimestamp = Date.now();
|
476
|
+
return config;
|
477
|
+
},
|
478
|
+
response: function(response) {
|
479
|
+
// Get the instance from the response object
|
480
|
+
var instance = response.resource;
|
481
|
+
|
482
|
+
// Augment the instance with a custom `saveLatency` property, computed as the time
|
483
|
+
// between sending the request and receiving the response.
|
484
|
+
instance.saveLatency = Date.now() - response.config.requestTimestamp;
|
485
|
+
|
486
|
+
// Return the instance
|
487
|
+
return instance;
|
488
|
+
}
|
489
|
+
}
|
490
|
+
}
|
491
|
+
});
|
492
|
+
|
493
|
+
Thing.save({foo: 'bar'}).$promise.then(function(thing) {
|
494
|
+
console.log('That thing was saved in ' + thing.saveLatency + 'ms.');
|
495
|
+
});
|
496
|
+
```
|
497
|
+
*
|
442
498
|
*/
|
443
499
|
angular.module('ngResource', ['ng']).
|
444
|
-
info({ angularVersion: '1.
|
500
|
+
info({ angularVersion: '1.8.0' }).
|
445
501
|
provider('$resource', function ResourceProvider() {
|
446
502
|
var PROTOCOL_AND_IPV6_REGEX = /^https?:\/\/\[[^\]]*][^/]*/;
|
447
503
|
|
@@ -671,34 +727,34 @@ angular.module('ngResource', ['ng']).
|
|
671
727
|
}
|
672
728
|
|
673
729
|
Resource[name] = function(a1, a2, a3, a4) {
|
674
|
-
var params = {}, data,
|
730
|
+
var params = {}, data, onSuccess, onError;
|
675
731
|
|
676
732
|
switch (arguments.length) {
|
677
733
|
case 4:
|
678
|
-
|
679
|
-
|
734
|
+
onError = a4;
|
735
|
+
onSuccess = a3;
|
680
736
|
// falls through
|
681
737
|
case 3:
|
682
738
|
case 2:
|
683
739
|
if (isFunction(a2)) {
|
684
740
|
if (isFunction(a1)) {
|
685
|
-
|
686
|
-
|
741
|
+
onSuccess = a1;
|
742
|
+
onError = a2;
|
687
743
|
break;
|
688
744
|
}
|
689
745
|
|
690
|
-
|
691
|
-
|
746
|
+
onSuccess = a2;
|
747
|
+
onError = a3;
|
692
748
|
// falls through
|
693
749
|
} else {
|
694
750
|
params = a1;
|
695
751
|
data = a2;
|
696
|
-
|
752
|
+
onSuccess = a3;
|
697
753
|
break;
|
698
754
|
}
|
699
755
|
// falls through
|
700
756
|
case 1:
|
701
|
-
if (isFunction(a1))
|
757
|
+
if (isFunction(a1)) onSuccess = a1;
|
702
758
|
else if (hasBody) data = a1;
|
703
759
|
else params = a1;
|
704
760
|
break;
|
@@ -712,14 +768,20 @@ angular.module('ngResource', ['ng']).
|
|
712
768
|
var isInstanceCall = this instanceof Resource;
|
713
769
|
var value = isInstanceCall ? data : (action.isArray ? [] : new Resource(data));
|
714
770
|
var httpConfig = {};
|
771
|
+
var requestInterceptor = action.interceptor && action.interceptor.request || undefined;
|
772
|
+
var requestErrorInterceptor = action.interceptor && action.interceptor.requestError ||
|
773
|
+
undefined;
|
715
774
|
var responseInterceptor = action.interceptor && action.interceptor.response ||
|
716
775
|
defaultResponseInterceptor;
|
717
776
|
var responseErrorInterceptor = action.interceptor && action.interceptor.responseError ||
|
718
|
-
|
719
|
-
var
|
720
|
-
|
777
|
+
$q.reject;
|
778
|
+
var successCallback = onSuccess ? function(val) {
|
779
|
+
onSuccess(val, response.headers, response.status, response.statusText);
|
780
|
+
} : undefined;
|
781
|
+
var errorCallback = onError || undefined;
|
721
782
|
var timeoutDeferred;
|
722
783
|
var numericTimeoutPromise;
|
784
|
+
var response;
|
723
785
|
|
724
786
|
forEach(action, function(value, key) {
|
725
787
|
switch (key) {
|
@@ -748,8 +810,15 @@ angular.module('ngResource', ['ng']).
|
|
748
810
|
extend({}, extractParams(data, action.params || {}), params),
|
749
811
|
action.url);
|
750
812
|
|
751
|
-
|
752
|
-
|
813
|
+
// Start the promise chain
|
814
|
+
var promise = $q.
|
815
|
+
resolve(httpConfig).
|
816
|
+
then(requestInterceptor).
|
817
|
+
catch(requestErrorInterceptor).
|
818
|
+
then($http);
|
819
|
+
|
820
|
+
promise = promise.then(function(resp) {
|
821
|
+
var data = resp.data;
|
753
822
|
|
754
823
|
if (data) {
|
755
824
|
// Need to convert action.isArray to boolean in case it is undefined
|
@@ -777,12 +846,14 @@ angular.module('ngResource', ['ng']).
|
|
777
846
|
value.$promise = promise; // Restore the promise
|
778
847
|
}
|
779
848
|
}
|
780
|
-
response.resource = value;
|
781
849
|
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
850
|
+
resp.resource = value;
|
851
|
+
response = resp;
|
852
|
+
return responseInterceptor(resp);
|
853
|
+
}, function(rejectionOrResponse) {
|
854
|
+
rejectionOrResponse.resource = value;
|
855
|
+
response = rejectionOrResponse;
|
856
|
+
return responseErrorInterceptor(rejectionOrResponse);
|
786
857
|
});
|
787
858
|
|
788
859
|
promise = promise['finally'](function() {
|
@@ -794,25 +865,8 @@ angular.module('ngResource', ['ng']).
|
|
794
865
|
}
|
795
866
|
});
|
796
867
|
|
797
|
-
|
798
|
-
|
799
|
-
var value = responseInterceptor(response);
|
800
|
-
(success || noop)(value, response.headers, response.status, response.statusText);
|
801
|
-
return value;
|
802
|
-
},
|
803
|
-
(hasError || hasResponseErrorInterceptor) ?
|
804
|
-
function(response) {
|
805
|
-
if (hasError && !hasResponseErrorInterceptor) {
|
806
|
-
// Avoid `Possibly Unhandled Rejection` error,
|
807
|
-
// but still fulfill the returned promise with a rejection
|
808
|
-
promise.catch(noop);
|
809
|
-
}
|
810
|
-
if (hasError) error(response);
|
811
|
-
return hasResponseErrorInterceptor ?
|
812
|
-
responseErrorInterceptor(response) :
|
813
|
-
$q.reject(response);
|
814
|
-
} :
|
815
|
-
undefined);
|
868
|
+
// Run the `success`/`error` callbacks, but do not let them affect the returned promise.
|
869
|
+
promise.then(successCallback, errorCallback);
|
816
870
|
|
817
871
|
if (!isInstanceCall) {
|
818
872
|
// we are creating instance / collection
|