0

I have a controller (MyCtrl). The first thing that is to be done is to make a http.get call and get the response and assign it to $scope.input. The rest of the controller depends on $scope.input. But the problem is the code in the controller tries to access $scope.input before the http call is finished.

How can I solve this?

app.controller('MyCtrl', function($scope, $http, $routeParams, factory) {
   factory.getInfo($routeParams.id) 
    .success(function(response) {
         //The factory code make the http.get call
           $scope.input = response;
    });

   //Rest of code accessing $scope.input before it is ready
});

P.S: I don't want to place the rest of controller code inside the success block

Thanks

9
  • Are you using angular-router or ui-router ? Commented Dec 28, 2015 at 4:47
  • I'm using routeProvider Commented Dec 28, 2015 at 4:49
  • Can't you wrap all your initialization logic inside a function and then call that function inside your success callback ? Commented Dec 28, 2015 at 4:53
  • @Arkantos I can do that. . The rest of the controller code has several functions and code blocks depending on $scope.input. So I'm afraid whether putting all that in one function would make sense in my case Commented Dec 28, 2015 at 4:57
  • As a matter of fact you're already placing all your logic inside your controller function :) With the above proposed change, you'll have nested function inside your controller. Now that you need to wait for some asynchronous call response, I think that's the easiest way to handle this. If you're at the luxury to change your router, ui-router has a resolve feature for these kind of scenarios. Commented Dec 28, 2015 at 5:07

1 Answer 1

1

Option-1 : Using Some intialize function

You can move your initialization logic to a function called initialize() and then call the function in the success callback of your AJAX call.

app.controller('MyCtrl', function($scope, $http, $routeParams, factory) {
   factory.getInfo($routeParams.id) 
    .success(function(response) {
           initialize(response);
    });

    function initialize(){
       /* Move only the logic that depends on response from AJAX call in to 
          this  method.

          All utility functions, event handlers on scope are still outside
          this function
        */

         $scope.input = response;
    }

});

Option-2 : Using resolve

You can also use the resolve feature to load all the dependencies before you initialize your controller like below.

In your router-config

$routeProvider
        .when('/home/:id', {
            templateUrl: 'home.html',
            controller: 'MyCtrl',
            resolve: {
                factory : 'factory',
                initData: function(factory,$route){
                   return factory.getInfo($route.current.params.id); 
                }
            }
        });

In your controller

app.controller('MyCtrl', function($scope, $http, initData){
  $scope.input = initData;
  // rest of your logic
});

For more info on this controller-activate & route-resolve pattern, you can refer to this and this.

Hope this helps :)

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.