1

I want to factor out the angularjs $http success callback function so that instead of having two (or N) anonymous callback functions I have one named callback function.

Here are the two controllers:

function CreateCurriculumCtrl($scope, $http, $location, select2Options){

    $scope.curriculumInfo = {};
    $scope.curriculumInfo.statusOK = true;
    $scope.select2Options = select2Options; 

    $scope.saveCurriculum = function(){
        $http.post('bignibou/curriculum/new', $scope.curriculumInfo).success(function(curriculumInfo) {
            if(curriculumInfo.statusOK == true){
                $scope.curriculumInfo.statusOK=true;
                $location.path('/view/'+curriculumInfo.curriculum.id);
            }
            else{
                $scope.curriculumInfo.statusOK = false;
                $scope.curriculumInfo.errors = curriculumInfo.errors;
            }           
        });
    };
}

function EditCurriculumCtrl($scope, $http, $location, select2Options, $routeParams){

    $scope.curriculumInfo = {};
    $scope.curriculumInfo.statusOK = true;
    $scope.select2Options = select2Options;
    $scope.id = $routeParams.id;

    $http.get('/bignibou/utils/findCurriculumById.json',{params: {id: $routeParams.id}}).success(
            function(curriculum){
                $scope.curriculumInfo.curriculum = curriculum;
            });

    $scope.editCurriculum = function(){
        $http.post('bignibou/curriculum/edit/'+$routeParams.id, $scope.curriculumInfo)
        .success(function(curriculumInfo) {
            if(curriculumInfo.statusOK == true){
                $scope.curriculumInfo.statusOK=true;
                $location.path('/view/'+curriculumInfo.curriculum.id);
            }
            else{
                $scope.curriculumInfo.statusOK = false;
                $scope.curriculumInfo.errors = curriculumInfo.errors;
            }           
        });
    };
}

I am not sure how to do that because what will become the named callback function has a couple of dependencies (i.e. $scope and $location).

If I extract the function (named callback) out of the angularjs controllers, then the named callback has no longer access to its dependencies.

Can anyone please help with factoring out the success callback function and making sure the dependencies are satisfied?

3 Answers 3

7

Just pass them as arguments.

First, $http.post expects the callback to accept one argument. So we write the function that post expects:

function (curriculumInfo) {
    // .....
}

But the body of the function needs access to $scope and $location. So we write a function that accepts those and return the function that post expects:

function (scope,location) {
    return function (curriculumInfo) {
        // ... use scope and location in here
    }
}

Now we can name the function appropriately. Lets see, it's handling the response to new curriculum so I'd call it either new_curriculum_callback or new_curriculum_callback or handle_new_curriculum to indicate that it's a callback:

function handle_new_curriculum (scope,location) {
    return function (curriculumInfo) {
    }
}

Now you can call it to return the callback function to post:

$http
    .post('bignibou/curriculum/new',$scope.curriculumInfo)
    .success(handle_new_curriculum($scope,$location));
Sign up to request clarification or add additional context in comments.

Comments

2

Create a Curriculum service and refactor every call to the backend into it. Your controllers shouldn't care on how to getting the data. Inject the Curriculum service into your controllers. Your controllers then simply call functions on the Curriculum service and get the data.

angular.module('resources.curriculum', ['..'])
.factory('Curriculum', function ($http, $q) {
  return {
    create: function(dataToSave) {
      var deferred = $q.defer()

      http.get('...').success(function(data) {
        deferred.resolve(data)
      }).error(function(err) {
        deferred.reject(err)
      })
      return deferred.promise
    }
  }
})
.controller('SomeCtrl', function($scope, Curriculum) {
  $scope.someValue = Curriculum.create($scope.someDataToSave)
})

3 Comments

It seems the $scope dependency is available only for controllers. And I need it in my service... Any idea?
In you controller you call the Curriculum service and handle the success callback using promises or a callback function. Example using callback function: Curriculum.create($scope.dataToSave, function(dataFromServer) { $scope.data = dataFromServer ))
I am not sure I am following you here... Can you please provide a more detailled code sample if possible?
0

You would probably want to create angularjs service and call particular request on click of some button. This way you call requests in a synchronous way.

1 Comment

Ummm. What do mean? The idea is not to make requests synchronous but to factor out what is now an anonymous callback into a named callback.

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.