Search code examples
javascriptangularjsangularjs-serviceangular-promiseangularjs-http

Use output from services to controllers


I want to result of my $http.get from my service to my controller.

myserviceSample.js

  function messagesService($q,$http){
    var messages;
    $http({
      method: 'GET',
      url: 'http://api.com/feedback/list'
    })
    .then(function success(response){

      messages = response.data;
      console.log(messages);
    },function error(response){
      console.log('error'+ response);
    });
    console.log(messages);

    return {
      loadAllItems : function() {
        return $q.when(messages);
      }
    };
  }

})();

mycontrollerSample.js

  function MessagesController(messagesService) {
    var vm = this;

    vm.messages = [];

    messagesService
      .loadAllItems()
      .then(function(messages) {
        console.log(messages);
        vm.messages = [].concat(messages);
      });
  } 
})();

The above code results gives undefined output. What i miss?


Solution

  • $q.when object does expect promise/object to make it working. In your case you have to pass promise object to $q.when as you are doing $http.get call. Here messages object doesn't hold promise of $http.get, so you could change the implementation of method like below.

    Service

    function messagesService($q,$http){
        var messages = $http({
          method: 'GET',
          url: 'http://api.com/feedback/list'
        })
        .then(function success(response){
           return response.data;
        },function error(response){
           return $q.reject('Error Occured.');
        });
    
        return {
          loadAllItems : function() {
            return $q.when(messages);
          }
        };
    }
    

    Then controller will resolve that promise & .then will do the trick

    function MessagesController(messagesService) {
        var vm = this;
        vm.messages = [];
        messagesService
          .loadAllItems()
          .then(function(messages) {
            console.log(messages);
            vm.messages = [].concat(messages);
          });
    } 
    

    Note: Using $q to create a custom promise, is considered as bad pattern when you have $http.get method there(which does return promise itself)

    Improved Implementation

    function messagesService($q, $http) {
      var messages, getList = function() {
        return $http({
          method: 'GET',
          url: 'http://api.com/feedback/list'
        })
        .then(function success(response) {
          messages = response.data
          return response.data;
        }, function error(response) {
          return $q.reject('Error Occured.');
        });
      };
    
      return {
        loadAllItems: function() {
          if (!data)
            return getList(); //return promise
          else
            return $q.resolve(messages); //return data
        }
      };
    };