2

I'm working on a sort of file-manager application that connects to a RESTFUL file api. On the angular app, each file and directory is an instance of angular $resource using the file-object property relativePathName as resource id .

js var File = $resource(url + '/:type/:id', {id: '@relativePathName', type: '@type'}, {…});

The problem is, when updating a file resource, the relativePathName parameter gets url encoded, e.g. / becomes %2F which causes the server to intercept the request before it hits the actual API (I assume the server treats this as a physical address and of returns a 404 response). The API is capable of treating whole url segments as a single param, so basically it'd treat path/to/file as a uri parameter of http://myapp.com/api/files/create/path/to/file and not as a different uri.

My question is, is there a way to modify the request url after it's being generated by the private Router instance inside of the resource constructor? If so, how (found nothing on this in the docs)?. What would be a possible solution? passing relativePathName as a parameter instead of declaring it as the resource id (which would require modifying the API)?

Thanks in advance.

Thomas

3 Answers 3

1

Using $resource is not the one stop shop for RESTful service calls, it is merely a convenience service for api's that are structured in a certain way. If $resource cannot do what you need, just create your own service using a mix of $resource and $http that that fits the api you are trying to call.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, that's probably the only way. After some tinkering I ended up extending the constructor retrieved by $resource() and override $get as this is the only method that is , in my case, critical with regards to encoded url params.
0

In our app we wanted a different URL for getByName requests, so we override the resource address with the URL parameter of the action getByName like so:

myapp.factory('ListGroup', ['$resource',
     function($resource) {

        return $resource(
            '/API/List/:Id',
            {
                Id:'@Id',
                Name:'@Name'
            },
            {
                getByName: {method: 'GET', url: '/API/List/Group/:Name', isArray: true}
            }
        );
}

]);

Comments

0

My question is, is there a way to modify the request url after it's being generated by the private Router instance inside of the resource constructor?

I'm not sure about inside of the resource constructor but you can use interceptors to programatically alter route urls after they have been generated by $resource.

structure

hooks.config.js
hooks.factory.js
hooks.module.js

hooks.module.js

module.exports = angular
                    .module("app.hooks", [])
                    .factory("hooks", require("./hooks.factory.js"))
                    .config(require("./hooks.config.js"));

hooks.config.js

module.exports = ["$httpProvider", function($httpProvider) {
    $httpProvider.interceptors.push("hooks");
}];

hooks.factory.js

module.exports = ["$q", "$location", function($q, $location) {

    var basePrefix = "/api/v1";

    return {
        //invoked on every http request
        request: function(request) {
            request.url = interpret(request.url);
            return $q.when(request);
        }
    };

    function interpret(str) {
        //if requesting an html template, don't do anything
        if (str.indexOf(".html") > -1)
            return str;
        //if you're accessing the api, append the base prefix globally here
        else
            return basePrefix + str;
    }
}];

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.