Question

I created resource instance with this code:

$scope.book = Book.get({bookId:1});

Here is service code:

var bookServices=angular.module('bookServices',['ngResource']);

bookServices.factory('Book',['$resource',
    function($resource){
        return $resource('/books/:bookId',{},{});
    }]);

Book has cover image, accessible by url: /books/:bookId/cover.png

How can I get url from resource instance?

$scope.book.$$url 

is undefined.

Was it helpful?

Solution

I think this is a view concern and should be handled there. I can't test this now, but my hunch would be to build the url in your view template.

So, the book detail template would be:

<div>
     <p>Name: {{ book.name }}</p>         
     <img ng-src="/books/{{ book.id }}/cover.png" alt="cover">
</div>

You might need to play with the relative path, but that should do the trick. You want to keep these concerns out out your controller and services, and angular comes with plenty of tools, like the ngSrc directive, to do just that.

EDIT

Perhaps to better answer the original question, here's another solution. Use the decorator pattern to extend the $resource service api to expose the url as a property of a resource object.

Decorate the $resource service like this:

function ResourceDecorator($delegate) {

  var decorator = function (url, paramDefaults, actions) {

    var resource = $delegate(url, paramDefaults, actions),
        getSave;

    // expose the parameterized url of the resource
    resource.$url = url;

    // expose urls for individual resources by extending
    // the get method to return a class object that has
    // a url property

    getSave = resource.get;

    resource.get = function(parameters, success, error) {

      var r = getSave(parameters, success, error),
              paramName;

      // get the name of the parameter, assuming just ONE            
      paramName = Object.keys(parameters)[0];

      // replace the parameter with it's value
      r.$url = url.replace(':' + paramName, parameters[paramName]);

      // return the decorated class object back
      return r;
    };

    return resource;

  };

  return decorator;

}

app.config(['$provide', function ($provide) {

    $provide.decorator('$resource', ['$delegate', ResourceDecorator]);

}]);

Then you will have the url available as a property on your resource object.

$scope.book.$url

Note that there's a whole wack of $resource scenarios that this simple example doesn't support, but it shows a proof of concept.

See this plunker.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top