35

I want to extract data from current URL and use it in controller. For example I have this url:

app.dev/backend/surveys/2

Bits that I want to extract:

app.dev/backend/ :type / :id

Is there anything in Angular that could help me with this task ?

3
  • 2
    look at $route and $routeParam Commented Dec 18, 2013 at 10:43
  • I forgot to say that the url is static and generated from Server side. Not with angular. If that even changes anything. Commented Dec 18, 2013 at 11:16
  • no, it does not matter how it was generated -- until you configured it properly in the .config block of the application. Commented Dec 18, 2013 at 11:26

6 Answers 6

53

To get parameters from URL with ngRoute . It means that you will need to include angular-route.js in your application as a dependency. More information how to do this on official ngRoute documentation.

The solution for the question:

// You need to add 'ngRoute' as a dependency in your app
angular.module('ngApp', ['ngRoute'])
    .config(function ($routeProvider, $locationProvider) {
        // configure the routing rules here
        $routeProvider.when('/backend/:type/:id', {
            controller: 'PagesCtrl'
        });

        // enable HTML5mode to disable hashbang urls
        $locationProvider.html5Mode(true);
    })
    .controller('PagesCtrl', function ($routeParams) {
        console.log($routeParams.id, $routeParams.type);
    });

If you don't enable the $locationProvider.html5Mode(true);. Urls will use hashbang(/#/).

More information about routing can be found on official angular $route API documentation.


Side note: This question is answering how to achieve this using ng-Route however I would recommend using the ui-Router for routing. It is more flexible, offers more functionality, the documentations is great and it is considered the best routing library for angular.

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

4 Comments

I was just wondering why the $on('$routeChangeSuccess') event handler is needed? I ask because when I implemented this solution (thanks for posting it by the way), I find I must have the event handler in my code or it simply doesn't work. To be more precise: it doesn't populate my $scope items with the values of the parameters, but it does if I leave the event handler in there. I can live with it, but was originally expecting to get the parameters after the website had finished loading.
To add to Mike's comment. If you add the $routeParams check within the $rootScope.$on('$routeChangeSuccess', ...) event, then it will be "stored" for all route changes, and will execute the callback upon every route change. If you only want to check the route parameters for the current controller (ie. only the route with the parameters), then just remove the $rootScope.$on(...) all together and check $routeParams by itself directly in the controller function.
worked for me without html5Mode. but my urls do have /#/ - im cool with the hash urls though
Yeah I am saying that in my last sentence, that you will have hashbang urls.
14

You could inject $routeParams to your controller and access all the params that where used when the route was resolved.

E.g.:

// route was: app.dev/backend/:type/:id

function MyCtrl($scope, $routeParams, $log) {
    // use the params
    $log.info($routeParams.type, $routeParams.id);
};

See angular $routeParams documentation for further information.

Comments

5

Better would have been generate url like

app.dev/backend?type=surveys&id=2

and then use

var type=$location.search().type;
var id=$location.search().id;

and inject $location in controller.

Comments

3

In your route configuration you typically define a route like,

.when('somewhere/:param1/:param2')

You can then either get the route in the resolve object by using $route.current.params or in a controller, $routeParams. In either case the parameters is extracted using the mapping of the route, so param1 can be accessed by $routeParams.param1 in the controller.

Edit: Also note that the mapping has to be exact

/some/folder/:param1

Will only match a single parameter.

/some/folder/:param1/:param2 

Will only match two parameters.

This is a bit different then most dynamic server side routes. For example NodeJS (Express) route mapping where you can supply only a single route with X number of parameters.

2 Comments

So currently I have this: $routeProvider.when('/backend/:bookId/:chapterId/:weeep', { controller: 'SurveyPages' }); But when I pass the $routeParams to SurveyPages controller and use console.log() to check it shows me empty object ? I am guessing I am doing something wrong here.
Do you have html5Mode enabled? $locationProvider.html5Mode(true);
2

ex: url/:id

var sample= app.controller('sample', function ($scope, $routeParams) {
  $scope.init = function () {
    var qa_id = $routeParams.qa_id;
  }
});

1 Comment

This answer would be made a lot clearer with a comment on what you're doing and why. You should also edit it to format the code correct (select the code and click the button that looks like "{}"). I have not done this myself since I'm not sure whether the code starts on the first or second line.
1

Just inject the routeParams service:

http://docs.angularjs.org/api/ngRoute.$routeParams

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.