0

I am trying to build an app which on login changes the state to a view with $state.go but when calling $state.go the controller is not instantiated as defined for that state.

Here is my state change logic (removing other code for brevity):

config(function($stateProvider, $urlRouterProvider) {
  $stateProvider
  .state('login', {
    url: "/",
    templateUrl: "templates/login.html",
    controller: 'LoginController'
  })
  // setup an abstract state for the tabs directive
  .state('tab', {
    url: "/tab",
    abstract: true,
    templateUrl: "templates/tabs.html"
  })

  // Each tab has its own nav history stack:
  .state('tab.dash', {
    url: '/dash',
    views: {
      'tab-dash': {
        templateUrl: 'templates/tab-dash.html',
        controller: 'DashboardController'
      }
    },
    resolve: {
      authenticated: ['RestService', function(restService) {
        return restService.authenticationStatus();
      }],
      sessionService: ['SessionService', function(sessionService) {
        return sessionService;
      }]
    }
  })

My LoginController is something like:

  // Perform the login action when the user submits the login form
  $scope.doLogin = function(loginForm) {
    if (loginForm.$invalid) {
        $log.debug('Invalid Form...', $scope.loginData);
        return;
    }
    $log.debug('Doing login', $scope.loginData);

    RestService.login($scope.loginData)
      .then(function(data) {
          $log.debug("Inside loginController...");
          $log.debug(data);
          $scope.$state.go("tab.dash");
      }, function(data) {
          $log.debug(data);
          $scope.formErrors = data.errors;
      });
  };

And my DashboardController is something like:

angular.module('starter.controller.dashboard', [])

.controller('DashboardController', ['$scope', '$log', '$http',
  function($scope, $log, $http) {
    $log.debug("reaching here..................");
    $log.debug($scope.authenticated);

}]);

Now when the login succeeds, the state is transitioned to /tab/dash but the controller is not instantiated i.e. the debug logs in DashboardController are not printed. If I directly navigate to /tab/dash then the controller does get instantiated and I do see the logs getting printed.

Moreover the value of "authenticated" passed via resolve in state definition is not available via scope in templates.

9
  • @JB Nizet: No I have added the 'starter.controller.dashboard' to the dependency of my main module and I am not seeing any errors in console. Moreover as stated in my question, if I navigate to state directly then the controller does get instantiated. If there was any error in dependency resolution, it should have shown error in console even when directly navigating to the state. Commented Mar 29, 2015 at 15:40
  • what does the code for authenticationStatus() look like? Resolves must complete before the controller is initialized, so the problem is likely in that function.... Commented Mar 29, 2015 at 16:04
  • @Claies: Even if I change the resolve to: resolve: { authenticated: function(restService) { return true; } } I still see the same behaviour. Commented Mar 29, 2015 at 16:17
  • does the controller initialize if you do not have a resolve option at all? Commented Mar 29, 2015 at 16:23
  • @Claies: No even after I remove the resolve option, still I don't see the DashController getting initialized. Commented Mar 29, 2015 at 16:28

1 Answer 1

0

Well turns out that the controller is getting instantiated but it gets instantiated only once. If I don't refresh the page while testing and just change the path then since the controller is already instantiated, it is not instantiated again. Only if I refresh the page (LoginPage) and then navigate to Dashboard page (via $state.go on logging in) the controller gets instantiated again.

And the issue with resolve data not available in the controller is because my assumption was that it is auto injected in $scope but actually it is not so. The resolve params get injected explicitly via the passed params to constructor function of controller and then one needs to assign the values manually in the scope. Something like:

.controller('DashboardController', ['$rootScope', '$scope', '$log', '$ionicLoading', '$http', 'authenticated',
  function($rootScope, $scope, $log, $ionicLoading, $http, authenticated) {
    $scope.authenticated = authenticated;
}]);
Sign up to request clarification or add additional context in comments.

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.