oxuser
oxuser

Reputation: 1327

How can I call a function in a controller from outside the controller

I have a controller like this:

function MyCtrl($scope) {

  $scope.doSomething = function(){
    alert("Do something!");
  }

}

And I have multiple views which depend on this (ie multiple of the below):

  <div ng-controller="MyCtrl">
    ...
  </div>

The problem is, the data the controller depends on needs to be loaded in the background (the controller does not load that data), and a callback (dataIsReady()) will be called after the data is ready.

function dataIsReady(){
  // TODO: call the doSomething() function
}

Now, I want to basically call the doSomething() function, which is inside MyCtrl, from the dataIsReady() function. How can I do that?

Upvotes: 0

Views: 5076

Answers (2)

Umur Kontacı
Umur Kontacı

Reputation: 35478

Notice: This approach in this answer is terribly wrong, one should not access to the scope of a controller outside of angular, or outside of controller at all. This would also be terribly slow if you try to call it several times. Other than that, it is fine. I am giving this answer because it is also the simplest way. I would never use that kind of code in production, though. The appropriate way is to write a service to communicate with the controller.

Given that you have defined $scope.doSomething in MyCtrl:

var scp = angular.element('[ng-controller="MyCtrl"]').scope();
scp.doSomething();

Will call doSomething method defined in the controller.

Upvotes: 2

GFoley83
GFoley83

Reputation: 3539

I think what you need is a data service, which you can then inject into your controller. You can call a function on your data service which will handle the retrieval of the data and return a "promise" which can then be used to trigger your callback function when the data has loaded. Have a look at the following code which is a slightly modified version from egghead.io:

Plunker Demo (w/ local storage): http://plnkr.co/edit/9w2jTg?p=preview

var myApp = angular.module('myApp', []);

myApp.factory('AvengersService', function ($http) {

    var AvengersService = {
        getAsyncCast: function () {           
            // $http returns a promise, which has a then function, which also returns a promise
            var promise = $http.get("avengers.json") // or some JSON service
                .then(function (response) {
                   // The 'then' function here is an opportunity to modify the response
                   // The return value gets picked up by the 'then' in the controller.
                   return response.data;
            });
            // Return the promise to the controller
            return promise;
        }
    };

    return AvengersService;
});

myApp.controller('AvengersCtrl', function($scope, AvengersService) {
    // Call the async method and then do something when the data is retrieved
    AvengersService.getAsyncCast()
        .then(function (asyncData) {
            // Callback logic that depends on the data goes in here
            console.info("Cast pulled async.");
            $scope.avengers.cast = asyncData;
        });              

});

Hope that helps.

Upvotes: 4

Related Questions