Closed plong0 closed 9 years ago
+1
We were having the same issue as well. It could very well be that we are flat out implementing it wrong but ... can confirm the issue and @plong0 fix.
+1 the same issue.
You can also inject the $route service which will show your params immediately.
angular.module('MyModule')
.controller('MainCtrl', function ($scope, $route) {
console.log('routeParams:'+JSON.stringify($route.current.params));
});
The $routeParams
service is populated asynchronously. This means it will typically appear empty when first used in a controller.
To be notified when $routeParams
has been populated, subscribe to the $routeChangeSuccess
event on the $scope
. (If you're in a component that doesn't have access to a child $scope
, e.g., a service or a factory, you can inject and use $rootScope
instead.)
module.controller('FooCtrl', function($scope, $routeParams) {
$scope.$on('$routeChangeSuccess', function() {
// $routeParams should be populated here
});
);
Controllers used by a route, or within a template included by a route, will have immediate access to the fully-populated $routeParams
because ng-view
waits for the $routeChangeSuccess
event before continuing. (It has to wait, since it needs the route information in order to decide which template/controller to even load.)
If you know your controller will be used inside of ng-view
, you won't need to wait for the routing event. If you know your controller will not, you will. If you're not sure, you'll actually have to explicitly allow for both possibilities. Subscribing to $routeChangeSuccess
will not be enough; you will only see the event if $routeParams
wasn't already populated:
module.controller('FooCtrl', function($scope, $routeParams) {
// $routeParams will already be populated
// here if this controller is used within ng-view
$scope.$on('$routeChangeSuccess', function() {
// $routeParams will be populated here if
// this controller is used outside ng-view
});
);
The reason your use of $timeout
works is because you happen to be waiting long enough to allow the router to finish its work. But this introduces a race condition and an unnecessary delay; subscribing to the routing event allows you to react as soon as possible without risk of reacting too soon.
when using multiple nested controllers, it seems the $routeChangeSucces function may hit multiple times and I seem to need the last one. So, for every nesting I need to wait for one more hit. It would be nice if this could 'somehow' be fixed I think.
I don't think this is a bug in Angular. Routing is inherently async. @elliterate is correct here. Either listen to the route change success event or put your route param dependent code in a route controller.
Assuming I have in my index.html file:
and a MainCtrl looking like:
$routeParams is coming up empty... unless I wrap it in a very short timeout:
I didn't experience the problem when I used yo cg-angular to generate my project, but started experiencing it after I rebuilt my project using yo angular-fullstack
A couple others having similar trouble: http://stackoverflow.com/questions/17519937/routeparams-is-empty-in-main-controller/22955711