How to get the Promise in Service and only send the data loaded to the control?

0

I have a json file with the following sample structure:

{"status":"ok","count":2,"count_total":54,"pages":27,"posts":[{"id":894,"type":"post","slug":"titulo-1","url":"url-titulo-1.html","status":"publish","title":"Tu00edtulo 1","content":"<p>Teste de texto 1<\/p>","date":"2016-10-13 16:24:36","modified":"2016-10-18 16:04:11","categories":[{"id":9,"slug":"historias","title":"Hist\u00f3rias","description":"","parent":0,"post_count":7}],"tags":[],"author":{"id":1,"slug":"ivan","name":"Ivan","first_name":"Ivan","last_name":"Ferrer","nickname":"Ivan","url":"","description":""},"comments":[],"attachments":[],"comment_count":0,"comment_status":"open","custom_fields":{}},{"id":895,"type":"post","slug":"titulo-2","url":"url-titulo-2.html","status":"publish","title":"Tu00edtulo 2","content":"<p>Teste de texto 2<\/p>","date":"2016-10-14 10:20:21","modified":"2016-10-18 19:02:11","categories":[{"id":9,"slug":"historias","title":"Hist\u00f3rias","description":"","parent":0,"post_count":7}],"tags":[],"author":{"id":1,"slug":"ivan","name":"Ivan","first_name":"Ivan","last_name":"Ferrer","nickname":"Ivan","url":"","description":""},"comments":[],"attachments":[],"comment_count":0,"comment_status":"open","custom_fields":{}}]}

I would like to work the query in the service and not in the controller, I would like to load Promise once, by calling the News service in my controller, and then using the display methods in the view. >

Service:

angular.module('starter.services', [])
.factory('News', function($http) {
  this.promiseRtn = function() {
    return $http.get('/path/data.json').then(function (response) {
      return response.data.posts;
    });
  }
  var promise = this.promiseRtn();
   console.log(promise.$$state);
   console.log(promise); 
   /* no console log a promisse está trazendo os dados,
      mas eu não sei como acessar os dados no retorno abaixo,
      pois ele traz o objeto num formato diferente 
      o qual desconheço (veja na imagem abaixo): */ 
  return {
    getAll: function() {
      return promise;
    },
    getById: function(idNews) {
      for (var i = 0; i < promise.length; i++) {
        if (promise[i].id === parseInt(idNews)) {
          return promise[i];
        }
      }
      return null;
    }
};

});

Controller:

angular.module('starter.controllers', [])
.controller('HomeCtrl', function($scope, News) {
    $scope.noticias = News.getAll();
})
.controller('NoticiaCtrl', function($scope, News, $stateParams) {
    $scope.noticia = News.getById($stateParams.idNews);
});

What I do not want:

It used to work like this in my controller, passing the responsibility of the request to the controller on each view call, making everything very slow:

//chamava e esperava o retorno no then
 News.getAll().then(function (data) {
    $scope.noticias = data;
  });

 //chamava e esperava o retorno no then passando a ID
 News.getById($stateParams.idNews).then(function (data) {
  $scope.noticia = data;
 });

And inside the service was like this:

return {
        getAll: function() {
          function() {
            return $http.get('/path/data.json').then(function (response) {
                   return response.data.posts;
            });
        },
        getById: function(id) {
          function(id) {
            return $http.get('/path/data-'+id+.'.json').then(function (response) {
                   return response.data.post;
            });
        },

But I had to query every time I ran one of these methods getAll() , getById() , making it very slow.

How the object is coming:

    
asked by anonymous 18.11.2016 / 13:50

1 answer

0

I solved the problem in service , using $rootScope to preserve the collection of the first query, and $q.defer() , to delay the return until the collection of "Promise ":

.factory('News', function ($http, $q, $rootScope) {
    var services = {
                    getById: getById,
                    getAll: getAll
                   };

    return services;
    $rootScope.collection = [];

    function getAll() {
        return $http.get('/path/data.json', { cache: true })
               .then(getAllComplete, getAllFail);
        function getAllComplete(response) {
            $rootScope.collection = response.data.posts;
            return response.data.posts;
        }

        function getAllFail(error) {
            console.error(error);
        }
    }

    function getById(id) {
        if ($rootScope.collection) {
            var deferred = $q.defer();
            for (var i = 0; i < $rootScope.collection.length; i++) {
                if ($rootScope.collection[i].id === parseInt(id)) {
                    deferred.resolve($rootScope.collection[i]);
                    break;
                }
            }
         return deferred.promise;
        }
        //caso a promise não seja atendida, o método abaixo é retornado:
         return $http.get('/path/data-'+id+'.json', { cache: true })
            .then(getByIdComplete, getByIdFail);

         function getByIdComplete(response) {
             return response.data.post;
         }

         function getByIdFail(error) {
             console.error(error);
         }
     }
});

And in controller , I kept .then() as it was, for example:

News.getById($stateParams.idNews).then(function(data) {
    $scope.noticia = data;
});
    
18.11.2016 / 17:34