34

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/

3
  • 1
    it might be a bug , i dont see why angular would force teh trailing slash to be removed Commented Jan 26, 2013 at 2:31
  • You can also add a # at the end of the url but there might be some unknown consequences. Commented Mar 3, 2014 at 21:54
  • 1
    @Breedly i just switch... thanks for helping me keep this up to date. Commented Dec 1, 2014 at 15:37

10 Answers 10

65

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;
});
Sign up to request clarification or add additional context in comments.

2 Comments

getting the error as TypeError: Cannot set property 'stripTrailingSlashes' of undefined
Note that you don't have to add this to your app it can be added to your resources module as well: angular.module('myresources',['ngResource']) .config(function($resourceProvider) { $resourceProvider.defaults.stripTrailingSlashes = false; })
35

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.

3 Comments

escaping the trailing slash ( 'foo/:id\\/' ) works for me ( v1.1.3 )
@vincent Sounds like that might break if they fix the bug in Angular
but firefox transform the escaping slash to %5C ... it's really annoying
20

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

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

1 Comment

Be careful here. If this would be used for GET with some params in your query string it will fail!
6

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.

1 Comment

Have you got any solution to your problem?
2

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

Comments

1

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}});
        }); 

Comments

1

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');
});

Comments

0

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.

Comments

0

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;

Comments

-2

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.

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.