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

Asked

Viewed 217 times

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":{}}]}

If you would like to work the query on the service and not on the controller, you would like to load Promise once, by calling the "News" service on my controller, and then using the view view methods.

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 don’t want:

Before it worked like this in my controller, passing the responsibility of the request to the controller to each call of the view, leaving 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 do the query every time I performed one of these methods getAll(), getById(), slowing him down pretty.

How the object is coming:

inserir a descrição da imagem aqui

1 answer

0


I solved the problem at service, using $rootScope to preserve the "Collection" of the first consultation, and $q.defer(), to delay the return until the "Collection" of "Promise" is answered":

.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 the controller, I kept the .then() as it was, example:

News.getById($stateParams.idNews).then(function(data) {
    $scope.noticia = data;
});

Browser other questions tagged

You are not signed in. Login or sign up in order to post.