restangular
restangular copied to clipboard
API enhancement: get full route for nested resource
If I use nested resources I sometimes have to deal with generic route names. Say I have a users
and companies
route and both have a nested resource address
, which I can operate on with users/:id/address
and companies/:id/address
.
Now I want to enhance the restangularized element with custom logic inside Restangular.setOnElemRestangularized
, but I need to treat the address of a user differently than the address of a company. I can't just look into the route
param, because it is address
in both cases. I need to check elem.parentResource.route
, too. It could look like this:
Restangular.setOnElemRestangularized(function(elem, isCollection, route) {
if(elem.parentResource.route + '/' + route === 'companies/address') { /* do stuff */ }
if(elem.parentResource.route + '/' + route === 'users/address') { /* do stuff */ }
});
This can become quite verbose and error prone. It becomes even worse with deeper nested resources or in more generic situations where I have to make sanity checks (e.g. is elem.parentResource
defined?).
It would be very useful to get the full route of a resource like this:
Restangular.setOnElemRestangularized(function(elem, isCollection, route) {
if(elem.getFullRoute() === 'companies/address') { /* do stuff */ }
if(elem.getFullRoute() === 'users/address') { /* do stuff */ }
});
.getFullRoute()
would basically recursively prepend every existing parentResource.route
separated by a /
. elem.getFullRoute()
would be equal to elem.route
for every non-nested resource.
function getFullRoute(elem) {
var parentRoute = '';
if(elem.parentResource) {
parentRoute = getFullRoute(elem.parentResource) + '/';
}
return parentRoute + elem.route;
}
What do you think?
I found this issue while looking for a way to do Restangular.extendModel(...)
with a route like 'clubs/members'. I haven't tried yet, but I would love to see the preferred syntax of the extendModel/extendCollection methods to be compatible.
Just ran into this issue, too. extendModel and extendCollection are effectively useless in the scenario I'm in due to the all or nothing nature of how routes are extended. /user/detail and /customer/detail, for instance.
+1
+1
I too am running into this. Looking for a good way to extendModel() on a nested resource. In my case, I have:
myApp.factory 'Gallery', (Restangular) ->
Restangular.service('galleries')
Gallery.one(id).getList("photos")
and I'd like to have all the returned photo objects extended. I tried extending it with the galleries route, but never managed to extend the photo model properly:
Restangular.extendModel 'galleries/:id/photos', (model) ->
model.testFunc = (msg) ->
console.log(msg)
model
I ran into the same issue. I have customers/contacts and suppliers/contacts which are different.
The next solution seems to work well :
- Define the getFullRoute method (this is an iterative version. don't know if recursive whould be better)
function getFullRoute(elem) {
var currentElem = elem
var fullRoute = [];
do {
fullRoute.splice(0, 0, currentElem.route);
currentElem = currentElem.parentResource;
}
while(currentElem !== null);
return fullRoute.join('/');
}
- Add line to config.transformElem to get the full route of the element and try to get the transformers of the full route before getting the transformers of the route.
config.transformElem = function(elem, isCollection, route, Restangular, force) {
if (!force && !config.transformLocalElements && !elem[config.restangularFields.fromServer]) {
return elem;
}
var fullRoute = getFullRoute(elem);
var typeTransformers = config.transformers[fullRoute] || config.transformers[route];
var changedElem = elem;
if (typeTransformers) {
_.each(typeTransformers, function(transformer) {
changedElem = transformer(isCollection, changedElem);
});
}
return config.onElemRestangularized(changedElem,
isCollection, route, Restangular);
};
With that small changes, extendModel
will work like this :
Restangular.extendModel('customers/contacts', function(model) {
// ...
});
Restangular.extendModel('suppliers/contacts', function(model) {
// ...
});
What do you think ?
My solution can be found at : https://github.com/vincentdieltiens/restangular
This issue is still open and still seems relevant. Is there a workaround or a fix? How can I apply custom methods to nested model objects?