2

So I have a controller and service pair that are functioning properly right now, but my boss wants me to move the success/error/finally blocks from the controller to the service.

Controller Function:

            $scope.createUserButton = function () {
                $scope.isBusy = true;
                creationService.makeNewUser($scope.form)
                .success(function (data) {
                    var user = JSON.parse(data);
                    if (typeof user !== 'undefined') {
                        $scope.testusers.push(user);
                    }

                }).error(function () {
                    notify({
                        message: 'Could not create user',
                        classes: 'alert-danger',
                        templateUrl: 'partials/settingNotification.html'
                    });
                }).finally(function () {
                    $scope.isBusy = false;
                });
            };

Service:

service('creationService', ['restfulRepo', '$http',
function (restfulRepo, $http) {
this.makeNewUser = function (tempuser) {
    return $http({
        url: 'http://localhost:60098/***/*************/******',
        data: tempuser, method: 'PUT'
    });
};
}]);

The problem that I'm having is that if I move the success or finally blocks to the service, then they don't have access to the isBusy flag or to the testusers array. The array is bound to a graph in the controller that displays the information handed back.

Microsoft Excel
  • 139
  • 2
  • 9
  • 1
    `$http` returns a promise, in your controller you can do this: `creationService. makeNewUser().then(function(){ $scope.isBusy = false; });` – Stubbies Jun 23 '16 at 16:19
  • 1
    https://docs.angularjs.org/api/ng/service/$http#!/ "The `$http` legacy promise methods `success` and `error` have been deprecated. Use the standard `then` method instead. If `$httpProvider.useLegacyPromiseExtensions` is set to `false` then these methods will throw `$http/legacy` error. " – Claies Jun 23 '16 at 16:56

3 Answers3

2

With my response, you can let data binding alleviate that for you. Notice how we set the controller & service isBusy variables.

Controller:

$scope.isBusy = creationService.isBusy; //1-way Data Binding
$scope.createUserButton = function () {
            creationService.isBusy = true;
            creationService.makeNewUser($scope.form).then(
                    function(user){
                       $scope.testusers.push(user);
                    }, function(error){
                       notify({
                       message: error,
                       classes: 'alert-danger',
                       templateUrl: 'partials/settingNotification.html'
                       });
                    });

        };

Service:

service('creationService', ['restfulRepo', '$http', '$q', function (restfulRepo, $http, $q) {
this.isBusy = false;

this.makeNewUser = function (tempuser) {
var defer = $q.defer();
  $http({
    url: 'http://localhost:60098/***/*************/******',
    data: tempuser, method: 'PUT'
  }).success(function (data) {
                var user = JSON.parse(data);
                if (typeof user !== 'undefined') {
                    defer.resolve(user);
                }else{
                   defer.reject("Undefined user");
                }
            }).error(function () {
                defer.reject('Could not create user');
            }).finally(function () {
                this.isBusy = false;
            });
     return defer.promise;
  };
}]);
jarodsmk
  • 1,584
  • 1
  • 17
  • 36
  • I had to make some slight changes. Thank you `var defer = $q.defer(); $http({ url: 'http://localhost:60098/api/createTestUsers/createUser', data: tempuser, method: 'PUT' }).success(function (data) { var user = JSON.parse(data); defer.resolve(user); }).error(function () { notify({ message: 'Could not create user', classes: 'alert-danger', templateUrl: 'partials/settingNotification.html' }); }); return defer.promise;` – Microsoft Excel Jun 23 '16 at 17:23
  • My absolute pleasure! – jarodsmk Jul 28 '16 at 07:50
0

Depends on what responsibilities the service has. This is an example if you consider your service just as a way to talk to a server.

And the controller is responsible of just getting the data from the service and doing something with it like binding it to the view or showing an error message.

Service:

service('creationService', ['restfulRepo', '$http',
    function (restfulRepo, $http) {
        this.makeNewUser = function (tempuser) {
            return $http({
                url: 'http://localhost:60098/***/*************/******',
                data: tempuser, method: 'PUT'
            }).then(function(){
                var user = JSON.parse(data);
                return user;
            }, function(e){
                //check server error response e to send the correct object to the controller
                throw {
                    message: 'Could not create user',
                    classes: 'alert-danger',
                    templateUrl: 'partials/settingNotification.html'
                };
            });
        };
    }]);

Controller:

$scope.createUserButton = function () {
    $scope.isBusy = true;
    creationService.makeNewUser($scope.form)
        .then(function (user) {
            if (typeof user !== 'undefined') {
                $scope.testusers.push(user);
            }
        }, function (e) {
            notify(e);
        })
        .finally(function () {
            $scope.isBusy = false;
        });
};
gaheinrichs
  • 505
  • 5
  • 12
0

Related: Injecting $scope into an angular service function()

how do i pass scope from controller to service in angularjs?

It might be best for you to just move both your data testusers and the isBusy boolean to the service. This way all your other controllers can access testusers and be controlled by the isBusy variable.

Service

service('creationService', ['restfulRepo', '$http',
function (restfulRepo, $http) {
this.testusers = []; // do whatever you want with it
this.isBusy = false;
this.makeNewUser = function (tempuser) {
    return $http({
        url: 'http://localhost:60098/***/*************/******',
        data: tempuser, method: 'PUT'
    });
};
this.toggleBusy = function(){
    this.isBusy = this.isBusy ? false : true;
};
this.createUserErr = function () {
                notify({
                    message: 'Could not create user',
                    classes: 'alert-danger',
                    templateUrl: 'partials/settingNotification.html'
                };
this.createUserSuc = function (data) {
                var user = JSON.parse(data);
                if (typeof user !== 'undefined') {
                    this.testusers.push(user);
                }

            }

}]);

Controller

        $scope.createUserButton = function () {
            creationService.toggleBusy();
            creationService.makeNewUser(creationService.createUserSuc)
            .success().error(creationService.createUserErr);
            }).finally(creationService.toggleBusy);
        };
Community
  • 1
  • 1
vtange
  • 639
  • 1
  • 5
  • 10