You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=martin%40gon%2eto&lc=US&item_name=Martin%20Gontovnikas¤cy_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted"Donate once-off to this project using Paypal")
5
5
[](https://www.gittip.com/mgonto/)
@@ -80,19 +80,22 @@ You can also **check out [a video introduction of a talk I gave at Devoxx France
80
80
-[How do I handle CRUD operations in a List returned by Restangular?](#how-do-i-handle-crud-operations-in-a-list-returned-by-restangular)
81
81
-[When I set baseUrl with a port, it's stripped out.](#when-i-set-baseurl-with-a-port-its-stripped-out)
82
82
-[How can I access the unrestangularized element as well as the restangularized one?](#how-can-i-access-the-unrestangularized-element-as-well-as-the-restangularized-one)
83
+
-[Restangular fails with status code 0](#restangular-fails-with-status-code-0)
83
84
-[Why does this depend on Lodash / Underscore?](#why-does-this-depend-on-lodash--underscore)
Restangular has several features that distinguish it from $resource:
92
95
93
96
***It uses [promises](http://docs.angularjs.org/api/ng.$q)**. Instead of doing the "magic" filling of objects like $resource, it uses promises.
94
97
***You can use this in $routeProvider.resolve**. As Restangular returns promises, you can return any of the methods in the `$routeProvider.resolve` and you'll get the real object injected into your controller if you want.
95
-
***It doesn't have all those `$resource` bugs**. Restangular doesn't have problem with trailling slashes, additional `:` in the URL, escaping information, expecting only arrays for getting lists, etc.
98
+
***It doesn't have all those `$resource` bugs**. Restangular doesn't have problem with trailing slashes, additional `:` in the URL, escaping information, expecting only arrays for getting lists, etc.
96
99
***It supports all HTTP methods**.
97
100
***It supports ETag out of the box**. You don't have to do anything. ETags and If-None-Match will be used in all of your requests
98
101
***It supports self linking elements** If you receive from the server some item that has a link to itself, you can use that to query the server instead of writing the URL manually.
Restangular depends on Angular and Lodash (or Underscore).
149
155
156
+
**[Back to top](#table-of-contents)**
157
+
150
158
# Production apps using Restangular
151
159
152
160
Each time, there're more Production WebApps using `Restangular`. If your webapp uses it and it's not in the list, please create an issue or submit a PR:
153
161
154
162
***Life360** is using Restangular to build the WebApp version of their platform
155
163
***Thomson Reuters** is using Restangular for the new Webapp they've built
164
+
***Quran.com** is using Restangular for their alpha/beta app and soon to be main site
165
+
166
+
**[Back to top](#table-of-contents)**
156
167
157
168
#Starter Guide
158
169
@@ -173,6 +184,8 @@ The Restangular service may be injected into any Controller or Directive :)
173
184
Note: When adding Restangular as a dependency it is not capitalized 'restangular'
174
185
But when injected into your controller it is 'Restangular'
@@ -536,6 +553,8 @@ You can set this to either `true` or `false`. By default it's false. If set to t
536
553
537
554
You can set here if you want to URL Encode IDs or not. By default, it's true.
538
555
556
+
**[Back to top](#table-of-contents)**
557
+
539
558
### Accessing configuration
540
559
541
560
You can also access the configuration via `RestangularProvider` and `Restangular` via the `configuration` property if you don't want to use the setters. Check it out:
@@ -544,6 +563,8 @@ You can also access the configuration via `RestangularProvider` and `Restangular
544
563
Restangular.configuration.requestSuffix='/';
545
564
````
546
565
566
+
**[Back to top](#table-of-contents)**
567
+
547
568
### How to configure them globally
548
569
549
570
You can configure this in either the `config` or the `run` method. If your configurations don't need any other services, then I'd recommend you do them in the `config`. If your configurations depend on other services, you can configure them in the `run` using `Restangular` instead of `RestangularProvider`
### How to create a Restangular service with a different configuration from the global one
610
633
Let's assume that for most requests you need some configuration (The global one), and for just a bunch of methods you need another configuration. In that case, you'll need to create another Restangular service with this particular configuration. This scoped configuration will inherit all defaults from the global one. Let's see how.
There're some times where you want to use Restangular but you don't want to expose Restangular object anywhere. For those cases, you can actually use the `service` feature of Restangular.
@@ -669,6 +694,8 @@ var Cars = Restangular.service('cars', Restangular.one('users', 1));
669
694
Cars.getList() // GET to /users/1/cars
670
695
````
671
696
697
+
**[Back to top](#table-of-contents)**
698
+
672
699
## Methods description
673
700
674
701
There are 3 sets of methods. Collections have some methods and elements have others. There are are also some common methods for all of them
@@ -683,6 +710,7 @@ These are the methods that can be called on the Restangular object.
683
710
***restangularizeElement(parent, element, route, queryParams)**: Restangularizes a new element
684
711
***restangularizeCollection(parent, element, route, queryParams)**: Restangularizes a new collection
685
712
713
+
**[Back to top](#table-of-contents)**
686
714
687
715
### Element methods
688
716
***get([queryParams, headers])**: Gets the element. Query params and headers are optionals
@@ -702,11 +730,13 @@ These are the methods that can be called on the Restangular object.
702
730
***getRestangularUrl()**: Gets the URL of the current object.
703
731
***getRequestedUrl()**: Gets the real URL the current object was requested with (incl. GET parameters). Will equal getRestangularUrl() when no parameters were used, before calling `get()`, or when using on a nested child.
704
732
***getParentList()**: Gets the parent list to which it belongs (if any)
705
-
***clone()**: Copies the element
733
+
***clone()**: Copies the element. It's an alias to calling `Restangular.copy(elem)`.
706
734
***plain()**: Returns the plain element received from the server without any of the enhanced methods from Restangular. It's an alias to calling `Restangular.stripRestangular(elem)`
707
735
***withHttpConfig(httpConfig)**: It lets you set a configuration for $http only for the next call. Check the Local Config HTTP section for an example.
708
736
***save**: Calling save will determine whether to do PUT or POST accordingly
709
737
738
+
**[Back to top](#table-of-contents)**
739
+
710
740
### Collection methods
711
741
***getList([queryParams, headers]): Gets itself again (Remember this is a collection)**.
712
742
***get([id]): Gets one item from the collection by id**.
@@ -724,9 +754,11 @@ These are the methods that can be called on the Restangular object.
724
754
***several(route, ids*)**: Used for RequestLess connections and URL Building. See section below.
725
755
***oneUrl(route, url)**: This will create a new Restangular object that is just a pointer to one element with the specified URL.
726
756
***allUrl(route, url)**: This creates a Restangular object that is just a pointer to a list at the specified URL.
727
-
***clone()**: Copies the collection
757
+
***clone()**: Copies the collection. It's an alias to calling `Restangular.copy(collection)`.
728
758
***withHttpConfig(httpConfig)**: It lets you set a configuration for $http only for the next call. Check the Local Config HTTP section for an example.
729
759
760
+
**[Back to top](#table-of-contents)**
761
+
730
762
### Custom methods
731
763
***customGET(path, [params, headers])**: Does a GET to the specific path. Optionally you can set params and headers.
732
764
***customGETLIST(path, [params, headers])**: Does a GET to the specific path. **In this case, you expect to get an array, not a single element**. Optionally you can set params and headers.
All custom methods have an alias where you replace `custom` by `do`. For example, `customGET` is equal to `doGET`. Just pick whatever syntax you prefer.
750
782
783
+
**[Back to top](#table-of-contents)**
784
+
751
785
## Copying elements
752
786
Before modifying an object, we sometimes want to copy it and then modify the copied object. We can't use `angular.copy` for this because it'll not change the `this` binded in the functions we add to the object. In this cases, you must use `Restangular.copy(fromElement)`.
753
787
788
+
**[Back to top](#table-of-contents)**
789
+
754
790
## Enhanced promises
755
791
756
792
Restangular uses enhanced promises when returning. What does this mean? All promises returned now have 2 additional methods and collection promises have 3. These are the methods:
The `$object` property is a new property I've added to promises. By default, it'll be an empty array or object. Once the sever has responded with the real value, that object or array is filled with the correct response, therefore making the ng-repeat work :). Pretty neat :D
812
850
851
+
**[Back to top](#table-of-contents)**
852
+
813
853
## Using Self reference resources
814
854
815
855
A lot of REST APIs return the URL to self of the element that you're querying. You can use that with Restangular so that you don't have to create the URLs yourself, but use the ones provided by the server.
Sometimes, we have a lot of nested entities (and their IDs), but we just want the last child. In those cases, doing a request for everything to get the last child is overkill. For those cases, I've added the possibility to create URLs using the same API as creating a new Restangular object. This connections are created without making any requests. Let's see how to do this:
There're sometimes when you want to set a specific configuration $http configuration just for one Restangular's call. For that, you can use `withHttpConfig`. You must call that method just before doing the HTTP request. Let's learn how to use it with the following example:
Let's assume that your API needs some custom methods to work. If that's the case, always calling customGET or customPOST for that method with all parameters is a pain in the ass. That's why every element has a `addRestangularMethod` method.
Alternatively, if you just want the stripped out response on any given call, you can use the .plain() method, doing something like this:
1234
+
1235
+
````javascript
1236
+
1237
+
$scope.showData=function () {
1238
+
baseUrl.post(someData).then(function(response) {
1239
+
console.log(response.plain());
1240
+
});
1241
+
};
1242
+
````
1179
1243
1180
1244
**Addendum :** If you want originalElement to be the original response object instead of having an original value for each key in your newResponse array, replace
This is typically caused by Cross Origin Request policy. In order to enable cross domain communication and get correct response with appropriate status codes, you must have the CORS headers attached, even in error responses. If the server does not attach the CORS headers to the response then the XHR object won't parse it, thus the XHR object won't have any response body, status or any other response data inside which typically will cause your request to fail with status code 0.
1262
+
1195
1263
#### Why does this depend on Lodash / Underscore?
1196
1264
1197
1265
This is a very good question. I could've done the code so that I don't depend on Underscore nor Lodash, but I think both libraries make your life SO much easier. They have all of the "functional" stuff like map, reduce, filter, find, etc.
1198
1266
With these libraries, you always work with immutable stuff, you get compatibility for browsers which don't implement ECMA5 nor some of these cool methods, and they're actually quicker.
1199
1267
So, why not use it? If you've never heard of them, by using Restangular, you could start using them. Trust me, you're never going to give them up after this!
1200
1268
1269
+
**[Back to top](#table-of-contents)**
1201
1270
1202
1271
# Supported Angular versions
1203
1272
1204
1273
Restangular supports all angular versions including 1.0.X, 1.1.X and 1.2.X (1.2.4 being the current at the time)
1205
1274
1206
1275
Also, when using Restangular with version >= 1.1.4, in case you're using Restangular inside a callback not handled by Angular, you have to wrap the whole request with `$scope.apply` to make it work or you need to run one extra `$digest` manually. Check out https://github.com/mgonto/restangular/issues/71
1207
1276
1277
+
**[Back to top](#table-of-contents)**
1208
1278
1209
1279
# Server Frameworks
1210
1280
@@ -1213,22 +1283,30 @@ Users reported that this server frameworks play real nice with Restangular, as t
1213
1283
* Ruby on Rails
1214
1284
* CakePHP, Laravel and FatFREE, Symfony2 with RestBundle, Silex for PHP
1215
1285
* Play1 & 2 for Java & scala
1286
+
* Dropwizard for Java
1216
1287
* Restify and Express for NodeJS
1217
1288
* Tastypie and Django Rest Framework for Django
1218
1289
* Slim Framework
1290
+
* Symfony2 with FOSRestBundle (PHP)
1219
1291
* Microsoft ASP.NET Web API 2
1220
1292
1293
+
**[Back to top](#table-of-contents)**
1294
+
1221
1295
# Releases Notes
1222
1296
1223
1297
New releases notes are together with releases in GitHub at: https://github.com/mgonto/restangular/releases
1224
1298
1225
1299
To see old releases notes, [you can click here](https://github.com/mgonto/restangular/blob/master/CHANGELOG.md)
1226
1300
1301
+
**[Back to top](#table-of-contents)**
1302
+
1227
1303
# Contributors
1228
1304
1229
1305
* Martin Gontovnikas ([@mgonto](https://twitter.com/mgonto))
1230
1306
* Paul Dijou ([@paul_dijou](https://twitter.com/paul_dijou))
1231
1307
1308
+
**[Back to top](#table-of-contents)**
1309
+
1232
1310
# License
1233
1311
1234
1312
The MIT License
@@ -1244,3 +1322,5 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
0 commit comments