Harshvardhan Solanki
Harshvardhan Solanki

Reputation: 677

AngularJs service returning null object to controller

I am calling a service method in my controller to return an object. I struggled a lot to figure out the exact implementation difference between a service and a factory.

According to what I learned service instantiates with new and returns this to the calling controller.

I am trying to accomplish the same here..calling a service function in controller and storing the returned object in controller's $scope.user variable as follows:

controller:

app.controller('LoginFormController',['$log','$scope','userAngService','userBean',function($log,$scope,userAngService,userBean){
    $scope.user = {};
    $scope.login = function(val){
        userAngService.login(val);
        $scope.user = userAngService.user;   //accessing service's user variable
        //$scope.user = userAngService.user;
        console.log($scope.user);    //empty object being logged in console
    };
}]);

service:

app.service('userAngService',['$http','$log','$rootScope','$location',function($http,$log,$rootScope,$location){
    this.user = {};
    this.login = function(val){
        console.log('from angular service');
        $http({
            method: 'GET',
            url: 'http://localhost:7070/messenger/webapi/messages'
        }).success(function(data){
            user = data;
            console.log(user);   //successfully logging "user" in console
        });
    };

    return this;
}]);

Above in the service the login function(val) is changing the user variable defined in the service itself.

I can make the function to return this.user but still am getting the same result.

What changes should I make here?

And here is what I am getting in console: console output

Upvotes: 0

Views: 2147

Answers (5)

codeninja.sj
codeninja.sj

Reputation: 4129

You are calling $http service internally on your userAngService service.

Its a asynchronous service call so, just return the promise object to the controller and then assign values to $scope.user.

Controller

    app.controller('LoginFormController',     ['$log','$scope','userAngService','userBean',function($log,$scope,userAngService,userBean){        
    $scope.login = function(val){
        userAngService.login(val).then(function(data){
            $scope.user = data;
            console.log($scope.user);                
        });         
    };
}]);

Service

app.service('userAngService',['$http','$log','$rootScope','$location',function($http,$log,$rootScope,$location){
    this.user = {};
    this.login = function(val){
        console.log('from angular service');
        return $http({
            method: 'GET',
            url: 'http://localhost:7070/messenger/webapi/messages'
        });
    };           
}]);

Upvotes: 1

Abhilash Augustine
Abhilash Augustine

Reputation: 4208

Service

app.service('userAngService',['$http','$log','$rootScope','$location',function($http,$log,$rootScope,$location){
    this.user = {};
    this.login = function(val){
        console.log('from angular service');
        // here you are returning Promise
        return $http({
            method: 'GET',
            url: 'http://localhost:7070/messenger/webapi/messages'
        }).success(function(data){
            user = data;
            console.log(user);   //successfully logging "user" in console

            return user;
        });
    };
}]);

The first thing is, you don't need to return anything from service. This is the one of the difference from factory. In factory you need to return an object, but no need to return any object in service

controller

app.controller('LoginFormController',['$log','$scope','userAngService','userBean',function($log,$scope,userAngService,userBean){
    $scope.user = {};
    $scope.login = function(val){
        userAngService.login(val).then(userName){
               $scope.user = userName;
               console.log($scope.user);
        };
    };
}]);

Upvotes: 1

Rajendra Khabiya
Rajendra Khabiya

Reputation: 2030

You have to user promise in order to get data from a service via HTTP request because what happened when your http request give response back to controller there is no handler to receive it.

Controller should be :

app.controller('LoginFormController',['$log','$scope','userAngService','userBean',function($log,$scope,userAngService,userBean){
    $scope.user = {};
    $scope.login = function(val){
        userAngService.login(val).then(function(res){
            $scope.user = res;   
        //$scope.user = userAngService.user;
        console.log($scope.user);
        console.log(userAngService.user);
        });

    };
}]);

Service should be :

app.service('userAngService',['$http','$log','$rootScope','$location', '$q',function($http,$log,$rootScope,$location,$q){
    this.user = {};
    this.login = function(val){
        var deferred = $q.defer();
        var promise = deferred.promise;
        console.log('from angular service');
        $http({
            method: 'GET',
            url: 'http://localhost:7070/messenger/webapi/messages'
        }).success(function(data){
            user = data;
            console.log(user);   //successfully logging "user" in console
            deferred.resolve(user);
        });
        return promise;
    };

    return this;
}]);

I have not tested this code and i think it will work for you but if not the case please let me know.

Upvotes: 0

Jakob
Jakob

Reputation: 104

Your Service needs to return an abject. This should work:

app.service('userAngService',['$http','$log','$rootScope','$location',function($http,$log,$rootScope,$location){
this.user = {};
this.login = function(val){
    console.log('from angular service');
    $http({
        method: 'GET',
        url: 'http://localhost:7070/messenger/webapi/messages'
    }).success(function(data){
        user = data;
        console.log(user);   //successfully logging "user" in console
    });
};

return this; 
}]);

or if you want to use private and public funtions (module pattern) in javascript. Do:

    app.service('userAngService',['$http','$log','$rootScope','$location',function($http,$log,$rootScope,$location){

var user = {};

var handleRequestData = function(data){
    user = data;
    console.log(user);   //successfully logging "user" in console
};

var login = function(val){
    console.log('from angular service');
    $http({
        method: 'GET',
        url: 'http://localhost:7070/messenger/webapi/messages'
    }).success(handleRequestData);
};

/* while you returning just the login function, user and handleRequestData stay private */
return {
    login: login
};

}]);

Upvotes: 0

Gary
Gary

Reputation: 2339

Your controller is logging a blank object which is correct since it is a blank object. Can you try this?

app.service('userAngService',['$http','$log','$rootScope','$location',function($http,$log,$rootScope,$location){
    var vc = this;
    vc.user = {};
    vc.login = function(val){
        console.log('from angular service');
        $http({
            method: 'GET',
            url: 'http://localhost:7070/messenger/webapi/messages'
        }).success(function(data){
            vc.user = data;
            console.log(user);   //successfully logging "user" in console
        });
    };
}]);

OR this...

app.service('userAngService',['$http','$log','$rootScope','$location',function($http,$log,$rootScope,$location){
    var vc = this;
    vc.user = {};
    vc.login = function(val){
        console.log('from angular service');
        $http({
            method: 'GET',
            url: 'http://localhost:7070/messenger/webapi/messages'
        }).success(function(data){
            $rootScope.$apply(function(){vc.user = data;});
            console.log(user);   //successfully logging "user" in console
        });
    };
}]);

Upvotes: 0

Related Questions