0

I am building a fairly complex service with lots of models and functions. Part of the service looks like this:

// Sports model
var sports = {
    list: function () {

        // Create our deferred promise
        var deferred = $q.defer();

        // Get our categories
        moltin.categories.list(0, 0).then(function (response) {

            // Create our list
            list = [];

            // Loop 6 times
            for (var i = 0; i < 6; i++) {

                // Get our column index
                var colIndex = i + 1;

                // Return our spliced array
                list.push(response.splice(0, 7));
            }

            // Resolve our list
            deferred.resolve(list);
        });

        // Return our promise
        return deferred.promise;
    }()
};

which is then assigned to the service and returned like this:

var service = {
    sports: sports
}

return service;

Now, as you can see I am calling an API (moltin is another service which returns a promise). In my controller I want to do this:

self.list = service.sports.list

Because the method is self executing I expected to actually have a list of categories, but instead I just get the promise. Does anyone know how I can get the list without having to do this:

service.sports.list().then(function (response) {
    self.list = response;
});
2
  • Did you try with?: self.list = response.data; Commented Oct 2, 2015 at 15:12
  • 2
    No, it is not possible to get the list outside in the way you're asking. you must use a callback. Commented Oct 2, 2015 at 15:14

2 Answers 2

1

No, that method is asynchronous, so there is no way to access it without chaining on to the promise.

As an aside, there is a little antipattern in your code too. You should not create a new deferred and return that - you should just return the list from your internal call back and return directly from the method:

var sports = {
    list: function () {

        // Get our categories
        return moltin.categories.list(0, 0).then(function (response) {

            // Create our list
            list = [];

            // Loop 6 times
            for (var i = 0; i < 6; i++) {

                // Get our column index
                var colIndex = i + 1;

                // Return our spliced array
                list.push(response.splice(0, 7));
            }

            return list;
        });

    }()
};

All other code remains the same.

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

Comments

0

You can't, but if this code is in your controller and you're using ng-route or ui-router you have a resolve method on the router that prevents the controller to be called before the promise is resolved, so you can have this in the router:

.when("/news", {
    templateUrl: "newsView.html",
    controller: "newsController",
    resolve: {
        initialData: function(newsControllerInitialData){
            return newsControllerInitialData();
        }
    }
})

and in the controller:

app.controller("newsController", function ($scope, initialData) {
    $scope.message = initialData.message;
    $scope.greeting = initialData.greeting;
});

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.