5

I am unable to wrap my brain around the concept of asynchronous requests.

I have a controller for my view, which is creating an object instance from a provider:

va.controller('VaCtrl',function($scope,$shipment){
    $scope.shipment = $shipment.Shipment();    
});

The provider:

Shipment.provider('$shipment',function(){

    this.$get = function($http){

        function Shipment(){

        }

        Shipment.prototype.fetchShipment = function(){
            var shipment = undefined;
                $http.post('../sys/core/fetchShipment.php',{
                        // some data to POST
            }).then(function(promise){
                    shipment = promise.data;
                });

            return shipment;
        };

        return {
            Shipment: function(){
                return new Shipment();
            }
        }
    }
});

My goal is to get access to the data from Shipment.prototype.fetchShipment() inside my controller. My approach:

$scope.fetchShipment = function(){
       var shipment = $scope.shipment.fetchShipment();
        console.log(shipment); // undefined
};

However, this will return undefined.

I read about $q, and defers, promises and callbacks, and now i am like WTF; all i want to do is to push the retrieved data to my controller, what is the best possible way to do so?

user2422960
  • 1,476
  • 6
  • 16
  • 28

2 Answers2

5

You should modify your code as shown below to return the promise from fetchshipment directly, and then use then() inside your controller.

Shipment.prototype.fetchShipment = function(){

    return $http.post('../sys/core/fetchShipment.php',{
        // some data to POST
    })
};


$scope.fetchShipment = function(){
    var shipment = $scope.shipment.fetchShipment().then(function(data){;
        console.log(data);
    });
};

Explanation to Code :

Calling $http return a promise which is resolved when you get the data from the server. In the code above, I have returned $http.post from service function which returns a promise. So in the controller you are waiting for promise to be resolved, and when the promise is resolved, the result is logged to the console.

Read about more promise documentation on angular:

Burn_E99
  • 1,098
  • 1
  • 17
  • 27
Ajay Beniwal
  • 18,857
  • 9
  • 81
  • 99
  • Gosh, i owe you one. If you had one, i would greatly appreciate a link to a further explanation, because at the moment, i see that this works but have not understood the concept behind – user2422960 Jul 23 '13 at 09:33
  • why have you set $scope.fetchShipment to have the same name as prototype.fetchShipment ? – FutuToad Feb 03 '14 at 14:56
4

Just the give you an example how to get your example working with your own promise. It's much more simple if you use $http builtin promise, so it's an $q-example:

angular.module('myApp', []).controller("myAppCtrl", function ($scope, $shipment) {
    $shipment.Shipment().fetchShipment().then(function (shipment) {
        $scope.shipment = shipment
    });
}).provider('$shipment', function () {
    this.$get = function ($http, $q) {

        function Shipment() {

        }

        Shipment.prototype.fetchShipment = function () {
            var defered = $q.defer();
            demodata = {name: "jan", id:8282};
            $http.post('/echo/json/', 'json=' + encodeURIComponent(angular.toJson(demodata)), {
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
                }
            }).then(function (response) {
                //resolve promise
                defered.resolve(response.data);
            });

            return defered.promise;
        };

        return {
            Shipment: function () {
                return new Shipment();
            }
        }
    }
});

<div ng-controller="myAppCtrl">{{shipment}}</div>

JSFiddle (use JSFiddle echo-service as data provider): http://jsfiddle.net/alfrescian/ayke2/

More about promises:

http://blog.parse.com/2013/01/29/whats-so-great-about-javascript-promises/ http://www.egghead.io/video/o84ryzNp36Q AngularJS : Where to use promises? stackoverflow.com/questions/15604196/… egghead.io/video/o84ryzNp36Q

Community
  • 1
  • 1
alfrescian
  • 4,079
  • 1
  • 18
  • 20