AngularJS – Calling a controller function from a service

All we need is an easy explanation of the problem, so here it is.

I’m so green at Angular, I’m not even sure I’ve been structuring a search for this correctly. The whole directive and service terminology is still confusing me some, but that isn’t my question.

I’ve read this excellent article series front to back:

Which is why I am at this point in my application. And why I know my question relates more to the relationship between services and controllers. Rather than syntax-related.

So here is an overview of the app:

I have one controller. This goes off and gets a bunch of farm data for the user using an AJAX call to a PHP file, and displays it on screen using it’s own $scope.

var masterApp = angular.module('masterApp', ['myFilters','commonControls']);

masterApp.controller('MasterCtrl', ['$scope','$http', '$filter', 'commonFarmSelector', 
    function($scope, $http, $filter, commonFarmSelector){


        $scope.masterCtrl.loadFarmData = function(farmId) {
            var postdata = {

            $'/service/farmproduction', postdata).success(function (data) {
                // Do stuff with the $scope using data


You will see I am injecting something called “commonControls”. This was a module I created to hold controls that will be reused by multiple controllers. In this case, a dropdown field that contains a list of farms the user has access to (also obtained by an AJAX call):

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

commonControlsApp.controller('farmSelectorCtrl', ['$scope', '$http',function($scope, $http) {

    $scope.farmSelectorCtrl ={}

    // Change entire farm view when a different farm is selected
    $scope.farmSelectorCtrl.switchUserFarm = function() {
        var farmId = $scope.farmSelectorCtrl.selectedUserFarm;
        $scope.masterCtrl.loadFarms(farmId); // !!! Direct link to masterCtrl

    // Get a list of the user's farms
    $'/service/userfarms').success(function (data) {
        $scope.farmSelectorCtrl.userFarms = data.getFarmsPerUserResult.farmIds;


This works fine. But as you can see, the farmSelector is directly linked to masterCtrl. And the behavior of that loadFarmData function is specific to that controller. In other words, it will only do things that apply to that page.

The thing is, this farmSelector will be used on other pages. And the precise behavior of a change event will be different for each page. So I am struggling to work out where this behavior should sit. And how it would be called dependent on the controller using the farmSelector.

The article I have linked above suggests this farmSelector should be in a service so it can be reused elsewhere. But I am still confused over how you could give a generic service a specific action to take when an event is triggered.

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

I highly recommend a service as well, for the same reason the article suggests. It also has a great answer to your problem.

The technical term for what you want is a calback function. It is, precisely, a specific action to take when an event is triggered, and the Services section of the article provides a good example of how to do this.

Take a look at this section of the Services article (which I’ve trimmed down to the important parts)

angular.module('', [])
  .factory('githubService', ['$http', function($http) {

    var doRequest = function(username) {
      return $http({
        url: ''

    return {
      events: doRequest


So we’ve got a service now, called githubService, which has one method: events (which is really just a different name for doRequest; I kept the rename so that it would match with the article’s code.)

Hidden here behind the scenes is the $q API, which is sometimes referred to as the ‘promise’ API. The function $http returns a ‘promise’ object, which is really just a way for the code to keep track of what should happen when the ‘promise’ is done. For example, let’s look at this next code (again, modified from the article’s version):

app.controller('ServiceController', ['$scope', 'githubService',
function($scope, githubService) {

  // uses the $http service to call the GitHub API
  // and returns the resulting promise
    .success(function(data, status, headers) {
         // do magic stuff with the result
         // (which is in the data param)
         $ =;


This is where the ‘magic’ is happening. Look at the call to success(), and you’ll see that they are actually passing a function that should be run when the request works. The function still has access to all the variables in the ServiceController due to closure, so it’s allowed to use $scope and other variables. However, it’s very possible to write a different success() method in every controller by passing a different function each time, which lets multiple controllers take different actions. When the request finishes, it will call every success function that it was given.

You could follow this code example and get a working model, but I also suggest that you take a look at $q in angular, and also take a look at this article about callback functions. You need to understand both to really get what’s going on, but the good news is that they are both used quite often in angular, so it will be worth your time.

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from or, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply