Keith Beard
Keith Beard

Reputation: 1611

Moving $http.post call into a service

I am new to AngularJS not stupid, LOL. I had this call in a controller, I wanted to move it to a service. I need to make it available to multiple controllers.

 $http.post("/admin/Leads/LoadLeads.ashx", dataObj)
    .success(function (response) {
        $scope.Leads = response.p;
    });

Here is what I have tried. Getting back a response cant assign the data the same way.

Service:

myLeadDashboard.factory('LeadsServiceTest',[function(){
            return {
                retrievePostData: function($http,dataObj){
                    return $http.post("/admin/Leads/LoadLeads.ashx", dataObj);
                    }
            }
        }]);

Controller:

 var LeadsPromise = LeadsServiceTest.retrievePostData($http,dataObj);
            LeadsPromise.then(function(data) {
                $scope.Leads = data.p;
            });

What am I doing wrong? What am I not Understanding? If you need more information about what I am doing please let me know. Thank you.

Upvotes: 1

Views: 691

Answers (3)

Paul Boutes
Paul Boutes

Reputation: 3315

When you declare your Service, you have to put the $http service as parameter of your service function. Then, $http service return promise.

When you use .then(), it returns a promise while .success() is more traditional way of registering callbacks and doesn't return a promise.

PS : a good tips is to wrap your services/controllers/etc.. declaration into anonymous function.

You can do the following :

Controller

(function(){

function Controller($scope, Service) {

  //Retrieve our promise
  var promise = Service.post([1,2,3]);

  promise.then(function(response){
    //Retrieve our data
    console.log(response.data);
  });

  promise.success(function(data){
    //Data is what i want, it is not raw data
    console.log(data)
  });

}

angular
.module('app', [])
.controller('ctrl', Controller);

})();

Service

(function(){

  function Service($http){


    function post(data){
      //Return promise
      return $http.post('path_to_url', data);
    }

    var factory = {
      post: post
    };

    return factory;

  }

  angular
    .module('app')
    .factory('Service', Service);

})();

Upvotes: 0

Brad Barber
Brad Barber

Reputation: 2963

The HttpPromise.sucess spreads the response object so that the first parameter is the data...$q.then gives you the raw response object. You can access the data from your controller with the following:

 var LeadsPromise = LeadsServiceTest.retrievePostData($http,dataObj);
 LeadsPromise.then(function(response) {
   $scope.Leads = response.data.p;
 });

Upvotes: 1

ajmajmajma
ajmajmajma

Reputation: 14216

Here is how I like to use angular services -

.service('mySpecialService', [
        '$q',
        'Restangular',
        function MyService($q, Restangular) {


            MyService.prototype.list = function() {
                return $q(function(resolve, reject) {
                    //make list call
                });
            };

            MyService.prototype.post = function(data) {
                return $q(function(resolve, reject) {
                   //make post call
                });
            };

            MyService.prototype.delete = function(id) {

                return $q(function(resolve, reject) {
                    //delete by id
                });
            };

            MyService.prototype.list = function list() {

                return $q(function(resolve, reject) {
                   //make list call
                });
            };

So I like to use $q, and also restangular in place of $http - but $http is fine if you like that. Then you inject the service where ever you mean to use it and call it!

So like - in a controller where you have it injected it could be like

 MyService.post(postData);

and because I use $q you have the options of using the promises like

  MyService.post(postData)
      .then(function(data){
        //call complete logic
      })
      .catch(function(err){
          console.log("error in post ", err);
      });  

Just note - if you don't use $q, you will have a .data layer.

Upvotes: 1

Related Questions