Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I return data from a $http.get() inside a factory in angularjs

I'm having a lot of trouble with this and I can't seem to find anything here on SO or Google that helps me spot what I'm doing wrong

<!DOCTYPE html>
<html data-ng-app="testApp">
   <head>
      <title></title>
   </head>
   <body>
      <div data-ng-controller="myController">
         {{test}}<br/>
         {{test2}}<br/>
         {{test3}}
         <ul>
            <li data-ng-repeat="member in members">{{ member.firstname}}</li>
         </ul>
      </div>
      <script type="text/javascript" src="angular.min.js"></script>
      <script type="text/javascript">
         angular.module('testApp', ['memberFactory']);

         angular.module('testApp',[])
         .factory('memberFactory', function($http){

            var obj = {};
            obj.data = "abcd";
            obj.getResponse = function(){
                var temp = {};
                $http.get('hello.php').success(function(data){
                        alert(data);
                        temp =data;

                });

                return "some return value";
            }

            return obj
         });

         function myController($scope, memberFactory){ 
            $scope.test= "testString";
            $scope.test2= memberFactory.data;
            $scope.test3= memberFactory.getResponse();

         }
      </script>
   </body>
</html>

the return "some return value"; works but when I try to return temp, its null. I have tried various ways to get this to work but I just can't seem to set the temp value inside the $http.get() function

It is probably something simple (or a silly mistake/misguided approach on my part). Any advice would be greatly appreciated

like image 925
jonnie Avatar asked Aug 07 '13 11:08

jonnie


1 Answers

What's happening here is a result of the asynchronous nature of $http.get, When you run $http.get it doesn't run in order. That is, it 'branches off' and runs along side the rest of the code. This is done to accommodate for the server latency.

Here's a bad visualisation.

.getResponse Called                Return Temp.
|-------------------|--------------|
                    |---------------------------------|
                    $http.get ~Waiting for Server~    Temp assigned to data.

Can you see how Temp is returned before it's been given a value?

Thankfully, you can use what Angular calls a promise, This is a variable which you can return from a function, that gets 'resolved' later. You instantiate a promise like this.

var myPromise = $q.defer();

You assign values to it by using

myPromise.resolve(data);

You can then return this promise later in the function, in the normal way. ie.

return myPromise.promise

Of course, for all of this you need the $q library, which you include in the function parameters.

like image 110
Matt Cooper Avatar answered Oct 01 '22 15:10

Matt Cooper