2017-03-03 1 views
0

Ich versuche, eine Methode zu erstellen, die ein Array von Objekten zurückgibt, nachdem die Objekte von einer API abgerufen wurden. Das Problem ist, dass die Rückkehr von der Fabrik geschieht, bevor alle Anrufe beendet sind. Ich habe versucht, $ q.defer zu verwenden, aber es sendet immer noch die Rückkehr, bevor es fertig ist zu versenden. Das ist, was ich bisher gefunden habe.Rückstellung der Fabrik zurückstellen, bis die Schleife vollständig beendet ist angularjs

angular.module('watchList').factory('storageService', ['$http', '$q', function ($http, $q) { 
storage = {}; 

storage.getMovies = function() { 

    var movies = localStorage.getItem('movies'); 
    var movieArray = angular.fromJson(movies); 
    var newArray = []; 
    var defer = $q.defer(); 

    angular.forEach(movieArray, function (id) { 
      newArray.push($http.get(api + id)); 
    }); 
    $q.all(newArray).then(function (response) { 
      defer.resolve(response); 
    }); 

    return defer.promise; 
} 

Dies ist der Controller, ich versuche, den Anruf von

angular.module('watchList').controller('watchListController', ['$scope', 'storageService', function ($scope, storageService) { 
$scope.movies = storageService.getMovies(); 

ich die Schleife alles fertig machen wollen, bevor sie die Array zurückgibt.

+0

Werfen Sie einen Blick hier. Es wird Ihnen helfen http://stackoverflow.com/questions/18983138/callback-after-all-asynchronous-foreach-callbacks-are-completed –

+0

Setzen Sie Ihre Rückkehr in eine Funktion und rufen Sie das von Ihrem API-Rückruf. Auf diese Weise werden Sie nichts zurückgeben, bis der Anruf beendet ist. – PersyJack

Antwort

0

Sie brauchen keine Versprechen zu erstellen, können Sie nur das Versprechen Rückkehr von dem Aufruf $q.all(newArray) zurückgegeben.

Die Sache ist, dass Sie nicht erwarten können, ein Ergebnis synchron zu erhalten, wenn es nur asynchron verfügbar wird. So müssen Sie bei der Verwendung von then halten:

storage.getMovies = function() { 
    var movies = localStorage.getItem('movies'); 
    var movieArray = angular.fromJson(movies); 
    var newArray = movieArray.map(function (id) { 
     return $http.get(api + id); 
    }); 
    return $q.all(newArray); 
} 

storageService.getMovies().then(function(movies) { 
    $scope.movies = movies; 
    // ... other code working with $scope.movies 
}); 

Side Anmerkung: die map Methode tut, was Sie mit forEach tun, aber sofort gibt das Array, das ganz praktisch ist.

+0

Ich benutze momentan eckig 1, die keine angular.map hat. Ich habe versucht mit angular.forEach aber es hat nicht funktioniert. – Knikedix

+0

Versuchen Sie stattdessen die Array-Methode 'map'. Siehe aktualisierten Code. – trincot

+0

Danke, das hat super funktioniert! – Knikedix

-1

getMovies wird sofort mit einem Versprechen zurückkehren. Sie müssen "dann" verwenden, um auf dieses Versprechen zu warten.

$scope.movies = storageService.getMovies().then((response) => ...) 
Verwandte Themen