0

I'm trying to make a method that returns an array of objects after getting the objects from an API. The problem is that the return from the factory happens before all the calls are finished. I've tried to use $q.defer but it still sends the return before it's ready to ship. This is what I've come up with so far.

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;
}

This is the controller that I'm trying to make the call from

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

I want the loop to finish everything before it returns the array.

2
  • Take a look here. It will help you stackoverflow.com/questions/18983138/… Commented Mar 3, 2017 at 18:03
  • Put your return in a function and call that from your api success callback. this way you won't return anything until the api call is completed. Commented Mar 3, 2017 at 18:14

2 Answers 2

0

You don't need to create a promise, you can just return the promise returned by the $q.all(newArray) call.

The thing is that you cannot expect to get a result synchronously when it only becomes available asynchronously. So you need to keep with using then:

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 note: the map method does what you do with forEach, but immediately returns the array, which is quite practical.

Sign up to request clarification or add additional context in comments.

2 Comments

I'm using angular 1 right now which doesn't have angular.map. I tried with angular.forEach but it did not work.
Try the array method map instead. See updated code.
-1

getMovies will return immediately with a promise. You need to use "then" to wait on that promise.

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.