Praveen D
Praveen D

Reputation: 2377

Angular js : resolve dependency route

I have $scope.question which has questions for all the page.

I want to loop through page wise questions. for this I wrote a function questionsCtrl. This function I am calling in config while setting route.

but here I am getting undefined.

Please suggest how to get data for page from $scope.questions.
app.js

 (function () {
    "use strict";
    var app = angular.module("autoQuote",["ui.router","ngResource"]);

    app.config(["$stateProvider","$urlRouterProvider", function($stateProvider,$urlRouterProvider){
        $urlRouterProvider.otherwise("/");

        $stateProvider
            .state("step1", {
              url : "",
              controller: "questionsCtrl",
            resolve: {
                pageQuestion: $scope.questions
            }
            })  
            .state("step2", {
              url : "/step2",
              controller: "questionsCtrl",
            })
    }]
    );
}());

questionCtrl.js

(function () {
    "use strict";

    angular
    .module("autoQuote")
    .controller("questionsCtrl",["$scope","$state","$q",questionsCtrl]);

    function questionsCtrl($scope,$state,$q) {
       console.log('here in get question for page: '+$state.current.name);
        //var deferred = $q.defer();
        if($state.current.name == "" || $state.current.name == "step1")
            {
                $scope.pageQuestion = $scope.RC1_Cars_v2;
            }
        else if($state.current.name == "step2")
            {
                $scope.pageQuestion = $scope.RC1_Drivers_v2;
            }
        //return deferred.promise;
        console.log($scope);
    }
}()); 

html

    <div class="container-fluid col-md-8">
    <div ng-controller="autoQuoteCtrl">

       <div ng-repeat="que in pageQuestion">
           <!-- pagequestion will be in loop here -->
       </div>


      </div>
    </div>

here is my plunker http://plnkr.co/edit/kLc6DPqzQgLNpUBaLtZi?p=preview for complete code.

Upvotes: 0

Views: 56

Answers (1)

LordTribual
LordTribual

Reputation: 4249

The controller for a view contains view specific logic. If you add a template to your states via template or templateUrl you will have access to your controller's scope within that template. As far as I understand your problem you want to provide data to your content before the state is being displayed. If you take a look at the documentation the resolve property is exactly what you are looking for:

You can use resolve to provide your controller with content or data that is custom to the state. resolve is an optional map of dependencies which should be injected into the controller.

However, you are using it incorrectly. You won't have access to $scope in a config block. What you have to do is provide a function to your resolve property as follows:

resolve: {
  pageQuestion: function(myService) {
    return myService.getData();
  }
}

As you can see in the code snippet above, I am using a function which injects a service called myService. The service is responsible for getting your data. In the example I assume that the service has a method getData which returns a promise. The ui-router will now wait for all promises to be resolved before showing the state. Once you have created such function, you can use the name of your resolve property (in this case pageQuestion) to inject your data into your view controller. So your question controller would look like this:

function questionsCtrl(pageQuestion) {
  this.pageQuestion = pageQuestion;
}

You simply inject your resolve into your controller and assign it to a view variable.

Notice, that I am assuming the controllerAs syntax for your state, so I can ommit the $scope and directly use this inside the controller. All you have to do is to add a property controllerAs to your state configuration as follows:

.state("step1", {
  ...
  controller: "questionsCtrl",
  controllerAs: 'vm'         
})

This has the advantage, that you won't run into scope problems (this has something to do with scope inheritance) in the long run. This is a great article on scopes.

Your view should look like this now:

<div class="container-fluid col-md-8">
  <div ng-repeat="que in vm.pageQuestion">
    <!-- pagequestion will be in loop here -->
  </div>
</div>

Here you access your data via vm, which comes from the controllerAs property in your state config. I would also suggest to use the template for your state and remove occurrences of ng-controller. You won't be needing this because you have a view controller declared for your state already. Additionally, ng-controller's make it difficult to propertly manage your state. You end up with a scope soup, and this is something you definietly want to avoid.

Upvotes: 3

Related Questions