1

I need to call the service variable in controller. I tried to call $scope.userData1.data.name outside the Service function , it is undefined. If I put {{userData1}} in template Messages Ctrl , it shows up all the data array including names.

I need to load the i-frame using the user_name variable.

angular.module('starter.controllers', [])


.factory('UserService', function($http) {
var data;   

      return{
          getData: function($http) {
                    return $http.get("http://www.website.com/index.php/id/user/call12").
                    success(function(response) {
                     /// console.log(JSON.stringify(response));
                      userData=response.data;
                            return userData;

                   }).error(function(data, status, headers, config) {
                     // log error
                    });
          }
    }
 })
 .controller('MessagesCtrl',function ($scope, Messages,$http,$ionicPopup,$timeout,$window,UserService,Outbox,$sce) {

    $scope.userData1 = {}; // updated
$scope.myCtrl2= function(UserService,$http) {
 UserService.getData($http).then(function(data) {
   $scope.userData1 = data;
 console.log($scope.userData1.data.name); // USERNAME exist
  var name= $scope.userData1.data.name;
});
}

$scope.myCtrl2(UserService,$http);

 var name= $scope.userData1.data.name; //undefined
 $scope.formData4.upload_url = $sce.trustAsResourceUrl("http://www.website.com/index.php/id/user/view_form/"+ name);

})

template :

<form ng-controller="MessagesCtrl"  ng-disabled="isRequesting">
<span class="item item-input"  >
     <span class="input-label">&nbsp;</span> 
<iframe id="iframe-123" src="{{formData4.upload_url}}" style="border: 0px none; height: 80px; margin: auto; width: 100%; overflow: hidden;" frameborder=0></iframe></span>    
</form>
xyonme
  • 395
  • 1
  • 7
  • 24
  • possible duplicate of [How to return the response from an Ajax call?](http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call) – Alexis King Jan 21 '15 at 05:57
  • @AlexisKing Hi Alexis. Response has been returned in good form. but the scope of response isnot useable outside the function which called Service. – xyonme Jan 21 '15 at 06:09
  • The problem is because when use construct the `MessagesCtrl`, the `$scope.userData1.data.name` has been evaluated before `callback` of `$http` has been fired -> got `undefined` because you have not initialize `$scope.userData1` yet. And another thing about your code, you do not need to inject `UserService` and and `$http` to your `$scope.myCtrl2` because of `javascript closure`. Take a look at this fiddle, I have already changed your $http to $timeout but it should work the same way. Hope it helps. http://jsfiddle.net/themyth92/w0st1y7e/ – themyth92 Jan 21 '15 at 07:56
  • hi @themyth92 hi thank you for looking at my codes. I have trouble using the service variable outside the function. in the function myCtrl2() , I can trace the username but using `$scope.userData1.data.name` I got undefined. do you understand my situation? – xyonme Jan 21 '15 at 08:25
  • on your jsfiddle , if I put `var name = $scope.userData1.data.name;// undefined` on the row below $scope.myCtrl2(); it will return undefined in my case – xyonme Jan 21 '15 at 08:26
  • `var name = $scope.userData1.data.name;` wil be evaluated first before callback inside your `myCtrl2` executed (in your case is `$scope.userData1 = data`). So you will definitely got `undefined` at `var name = $scope.userData1.data.name;`. As long as the callback has finished executed then your `$scope.userData1.data.name` got some value instead of `undefined`. – themyth92 Jan 21 '15 at 08:38
  • I see. how do I set `var name = $scope.userData1.data.name;` to be evaluated after the service call? – xyonme Jan 21 '15 at 08:44
  • Take a look at this simplified fiddle for more understanding about javascript `callback` http://jsfiddle.net/themyth92/gvhd57ch/. Hope it helps :) – themyth92 Jan 21 '15 at 08:45
  • You can use a $watch for your case. Fiddle http://jsfiddle.net/themyth92/w0st1y7e/1/ or you can follow @cheziHoyzer answers – themyth92 Jan 21 '15 at 08:48
  • from your jsfiddle. i think understand what you are saying the script is wholely evaluated before doing the function? – xyonme Jan 21 '15 at 08:53

1 Answers1

1

You got undefined because at this point, the answer (http.get) not yet return from the server.
You have to ensure this function $scope.myCtrl2(UserService,$http) received the answer asynchronous before you can call to the next line (var name= $scope.userData1.data.name;).

The best solution is to use promise - $q service like this:

.controller('MessagesCtrl',function ($scope, Messages,$http,$ionicPopup,$timeout,$window,UserService,Outbox,$sce,$q) {

    $scope.userData1 = {}; // updated
    $scope.myCtrl2= function(UserService, $http) 
    {
       var deferred = $q.defer();
     UserService.getData($http).then(function(data) 
       {
         $scope.userData1 = data;
         console.log($scope.userData1.data.name); // USERNAME exist
         var name= $scope.userData1.data.name;

           deferred.resolve();
      });
          return deferred.promise;
    }

  $scope.myCtrl2(UserService,$http).then(function(){
      var name= $scope.userData1.data.name; //Now you got the answer!!!
      $scope.formData4.upload_url = $sce.trustAsResourceUrl("http://www.website.com/index.php/id/user/view_form/"+ name);
  });
})
cheziHoyzer
  • 4,803
  • 12
  • 54
  • 81