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 ?

sarunast
  • 2,443
  • 3
  • 27
  • 37

6 Answers6

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.

sarunast
  • 2,443
  • 3
  • 27
  • 37
  • 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. – Mike Rouse Nov 10 '14 at 15:33
  • 1
    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. – Ryan Weiss Dec 12 '14 at 03:50
  • worked for me without html5Mode. but my urls do have `/#/ ` - im cool with the hash urls though – David Jun 02 '15 at 18:28
  • Yeah I am saying that in my last sentence, that you will have hashbang urls. – sarunast Jun 03 '15 at 06:16
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.

fdomig
  • 4,417
  • 3
  • 26
  • 39
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.

Himanshu Chandra
  • 197
  • 4
  • 14
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.

Index
  • 2,351
  • 3
  • 33
  • 50
  • 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. – sarunast Dec 18 '13 at 11:05
  • 1
    Do you have `html5Mode` enabled? `$locationProvider.html5Mode(true);` – Mouagip Dec 18 '13 at 11:24
2

ex: url/:id

var sample= app.controller('sample', function ($scope, $routeParams) {
  $scope.init = function () {
    var qa_id = $routeParams.qa_id;
  }
});
trollr
  • 1,095
  • 12
  • 27
NgocSon
  • 21
  • 1
  • 4
    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. – DavidW Sep 02 '15 at 17:09
1

Just inject the routeParams service:

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

xmysteriox
  • 129
  • 3