Nix
Nix

Reputation: 58522

Angular trailing slash for resource

My api requires a trailing slash for api calls. I was wondering how to pull that off with angular.

So i need to be able to access /tasks/ or a /tasks/xxxx/. I attempted to do it via:

angular.module('taskServices', ['ngResource']).
        factory('Tasks', function($resource){
            return $resource('/tasks/:task_id/', {}, {
                 query: {method:'GET', 
                         params:{},
                         isArray:true}
            });
 });

and a

$scope.tasks = Tasks.query(); 

But it results in a /tasks or a tasks/xxx query.

How can i force it to always be /tasks/ and /tasks/xxx/

Upvotes: 34

Views: 29944

Answers (10)

johnleo natural
johnleo natural

Reputation: 1

http://localhost:4200/detail/filing/? do you encounter this issue they add question mark after slash in angular 18|

this is my routing

export default [
    {
        path: 'filing',
        redirectTo: "filing/",

        pathMatch: 'full',
    },
    {
        path: 'filing/:id',
        component: FilingComponent,

    },



] as Routes;

Upvotes: 0

Marco Fucci
Marco Fucci

Reputation: 1854

This seems to have been fixed: https://github.com/angular/angular.js/pull/5560

You can now configure it this way:

app.config(function($resourceProvider) {
  $resourceProvider.defaults.stripTrailingSlashes = false;
});

Upvotes: 65

Max Tepkeev
Max Tepkeev

Reputation: 2786

One can use http interceptors for all or specific urls, e.g. api urls:

app.factory('myHttpInterceptor', function ($q) {
    return {
        'request': function(config) {
            if (config.url.indexOf('/api/') != -1 && config.url.slice(-1) != '/') {
                config.url += '/';
            }
            return config || $q.when(config);
        }
    };
});

app.config(function($httpProvider) {
    $httpProvider.interceptors.push('myHttpInterceptor');
});

Upvotes: 1

Alexandre Simões
Alexandre Simões

Reputation: 1295

For AngularJS clients that use django-rest-framework, just use angular-django-rest-resource. Worked great.

Upvotes: 2

mpaolini
mpaolini

Reputation: 1344

adding a space at the very end of the url template works here (tested with angular 1.2.0):

{url: '/user/:id/ '}

Upvotes: 20

georges
georges

Reputation: 233

I am able to get over the Firefox encoding issue by adding this to the ngResource before composing the final url:

url = url.replace(/\\/,"/");

This allows the slash escape fix for Chrome/Safari to work well on Firefox.

app.factory('Things', function($resource){
        return $resource('/api/v1/thing\\/', {}, {
              query: {method:'GET', params:{},isArray:true}});
        }); 

Upvotes: 1

ako977
ako977

Reputation: 782

As a work-around for this until/if they ever change the AngularJS source, I set a .htaccess rewrite rule to add a trailing slash to all incoming requests to the webserver.

RewriteCond %{REQUEST_URI} !(/$|\.)
RewriteCond %{REQUEST_METHOD} GET
RewriteRule (.*) %{REQUEST_URI}/ [R=301,L]

Downsides of this approach:

  • Network traffic of RESTful calls get 301 redirected, so you see requests being sent twice
  • This works only for GET requests (note the restriction in my example), if the rewrite receives POST, DELETE, PUT requests and redirects, it does so as a GET request of the same URL, which may not be what you want of course, since you lose your payload.

Upvotes: 0

Andrew Hayes
Andrew Hayes

Reputation: 61

Adding the 2 back-slashes to escape the trailing slash on the URL worked for me on Chrome and Safari.

Firefox however decides that its a good idea to remove the trailing slash from the URL and encode the backslash that was escaping the forward slash to %5C...great :-) So in the example above you'd get http://example.com/controller/save%5C, which then 404s at the server.

I'm using Django+TastyPie for my project and need the trailing slash on the URL, I'll be looking to modify ngResource rather than dropping down to $http for everything as the lowest common denominator.

Upvotes: 6

Simon Guest
Simon Guest

Reputation: 2162

Vincent's escaping of the trailing slash (add two backslashes and a forward slash (http://example.com/controller/save\\/) to the end of the URL) worked for me.

Upvotes: -2

pkozlowski.opensource
pkozlowski.opensource

Reputation: 117370

The trailing slash is explicitly removed in this line of AngularJS source code. I'm not fully sure what was the rationale behind this code but there is already an issue opened for this: https://github.com/angular/angular.js/issues/992

As noted in the mentioned issue the $resource factory is great for RESTful endpoints that conform to a certain specification. While $resource will do do great job talking to back-ends conforming to a this specification, it has limitations that might rule it out for back-ends that don't obey a contract expected by the $resource. In such a case the best way forward is to switch to using the lower-level $http service as noted in this question: Recommended way of getting data from the server

$http is a very powerful and flexible service and allows full control over URLs, parameters sent etc.

Upvotes: 35

Related Questions