0

I've spent quite alot of time going over AngularJS these past few days, it's starting to all click now :) but the one question i can't seem to answer is how i get my factory to return the data as JSON - not as a promise OR even if i should!

There are a few reasons i can't see the result, A) the promise is incomplete, B) I shouldn't be doing it this way and should actually just stick with the 'then()' in the controller. Ideally i want to write one line in the controller but i always get an undefined unless i follow the pattern in the example.

Am i going against the grain on this where i don't need to?

    //  Will go into application.js
    (function () {
        var app = angular.module("ngOrderApp", []);
    }());

    //  Will go into orderFactory.js
    (function () {
        var order = function ($http) {
            var getOrdersJson = function () {
                return [{ OrderId: 101 }, { OrderId: 102 }, { OrderId: 103 }]; 
            }
            var getOrdershttp = function () {
                return $http.get('api/order')
                  .success(function (result) {
                      return result.data;
                  });
            }
            return {
                getOrdersJson: getOrdersJson,
                getOrdershttp: getOrdershttp
            };
        }
        var app = angular.module("ngOrderApp").factory("order", order);
    }());

    //  Will go into orderController.js
    (function () {
        var app = angular.module("ngOrderApp").controller('OrderController', function ($scope, order) {

            $scope.jsonorders = order.getOrdersJson();

            order.getOrdershttp().then(function (result) {
                $scope.httporders = result.data;
            });

        });
    }());

3 Answers 3

2

The whole point of promises is that you can't get the result of an asynchronous operation immediately.

So yes, you should use then to get its eventual result. It's three lines instead of one, but that shouldn't really be a problem. Once you get used to using promises, I'm sure you won't see it as so much of a big deal.

If that really doesn't sit well with you, you could consider using a $resource instead of using $http directly. This essentially allows you to assign a value directly to the place you want it instead of using then, and the rest of its contents will be filled in (asynchronously) when the request ultimately completes. Bear in mind that this still will not allow you to immediately access the result value. That's just not possible when you're working with asynchrony.

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

Comments

1

Binding directly to a promise worked in previous version of angular, but they got rid of this feature (I don't exactly know why) so, yes, just stick with the 'then()' in the controller.

Comments

0

Well this depends on the data that you are fetching. You could do a pre-fetch in your factory and store the data into a private variable like so:

(function () {
        var order = function ($http) {
            var getOrdersJson = function () {
                return [{ OrderId: 101 }, { OrderId: 102 }, { OrderId: 103 }]; 
            }
            var getOrdershttp = function () {
                return $http.get('api/order')
                  .success(function (result) {
                      return result.data;
                  });
            }

            var orders = [];
            getOrdershttp().then(function(res) {
               orders = res.data;
            });

            function getCahcedOrders(){ return orders; };

            return {
                getOrdersJson: getOrdersJson,
                getOrdershttp: getOrdershttp,
                getChacedOrders: getChacedOrders
            };
        }
        var app = angular.module("ngOrderApp").factory("order", order);
    }());

And this way your controller will only contain:

$scope.orders = order.getCachedOrders();

This is just a different approach to get rid of the .then() but you can do this only if you know for sure that you only need those orders fetched once. Otherwise you need to go with a promise. Also if you want to go with this approach you need to prefetch your orders when your app stars something like this:

(function () {
        var app = angular.module("ngOrderApp", []);

        app.run(['order'], function() {});
    }());

So you have some kind of guarantee that your orders will be loaded when you will try to access them. The run function runs when your Angular app kickstars so if you load your factory there the $http will begin fetching your data and populate the orders array so you can use it in your app.

Again, it depends on what do you want to achieve in the end. You can compromise and have a lighter controller but you can risk not getting your fetched data in time (if you have a lot of orders). I wouldn't stress so much over a few extra lines of code as long as they are doing their job and are written correctly.

Hope this information helped.

Good luck!

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.