Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

$routeParams is empty in main controller

Tags:

I have this piece of layout html:

<body ng-controller="MainController">
  <div id="terminal"></div>

  <div ng-view></div>

  <!-- including scripts -->
</body>

Now apparently, when I try to use $routeParams in MainController, it's always empty. It's important to note that MainController is supposed to be in effect in every possible route; therefore I'm not defining it in my app.js. I mean, I'm not defining it here:

$routeProvider.when("/view1", {
  templateUrl: "partials/partial1.html"
  controller: "MyCtrl1"
})

$routeProvider.when("/view2", {
  templateUrl: "partials/partial2.html"
  controller: "MyCtrl2"
})

// I'm not defining MainController here!!

In fact, I think my problem is perfectly the same as this one: https://groups.google.com/forum/#!topic/angular/ib2wHQozeNE

However, I still don't get how to get route parameters in my main controller...

EDIT:

What I meant was that I'm not associating my MainController with any specific route. It's defined; and it's the parent controller of all other controllers. What I'm trying to know is that when you go to a URL like /whatever, which is matched by a route like /:whatever, why is it that only the sub-controller is able to access the route parameter, whereas the main controller is not? How do I get the :whatever route parameter in my main controller?

like image 721
Derek Chiang Avatar asked Jul 08 '13 05:07

Derek Chiang


3 Answers

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 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
  });
);
like image 194
Ian Lesperance Avatar answered Dec 01 '22 00:12

Ian Lesperance


As an alternate to the $timeout that plong0 mentioned...

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));
  });
like image 24
Sean McClory Avatar answered Dec 01 '22 00:12

Sean McClory


I have the same problem.

What I discovered is that, $routeParams take some time to load in the Main Controller, it probably initiate the Main Controller first and then set $routeParams at the Child Controller. I did a workaround for it creating a method in the Main Controller $scope and pass $routeParams through it in the Child Controllers:

angular.module('MyModule')
  .controller('MainController', ["$scope", function ($scope) {
    $scope.parentMethod = function($routeParams) {
     //do stuff
    }
  }]);

angular.module('MyModule')
  .controller('MyCtrl1', ["$scope", function ($scope) {
    $scope.parentMethod($routeParams);
  }]);

angular.module('MyModule')
  .controller('MyCtrl2', ["$scope", function ($scope) {
    $scope.parentMethod($routeParams);
  }]);
like image 38
André Mendonça Avatar answered Nov 30 '22 23:11

André Mendonça