0

I have a factory where I am pulling data from an API and trying to assign the results to a variable. Everytime I run, I get my variable is undefined. Any way in which I can pass the results to my variable from an async call? For instance in my case. My factory looks like this.

angular.module('MyApp.services', [])
.factory('ReportService', ['$http', '$window', '$upload', 'AuthService', function ($http, $window, $upload, AuthService) {
    return {
        findAll: function (criteria) {
            criteria = criteria || [];

            return $http.get(BASE_URL + '/ajax.php?action=reports.all&' + criteria.join('&'));
        }        
    }
}])

then in my controller

.controller('MyViewController', [
    '$scope', 'ReportService', 'toaster', '$modal', '$rootScope',
    function ($scope, ReportService, toaster, $modal, $rootScope) {
        ReportService
            .findAll()
            .then(
            function success(response, status, headers, config) {
                $scope.reports = response.data.reports;
            },
            function error(response, status, headers, config) {
                console.log('error');
            });
    //console.log($scope.reports) returns undefined here.
    }
]);

How do I go about getting the variable populated at the global level for the controller?

JLRishe
  • 99,490
  • 19
  • 131
  • 169

2 Answers2

0

The reason your variable is undefined when you call console.log($scope.reports) is because your code is asynchronous. Thus you're executing console.log($scope.reports) before the http request returns and causes the $scope.reports variable to be assigned with the returned data. This is just the nature of asynchronous code.

Here's what happens chronologically:

  1. You call ReportService.findAll()
  2. You call console.log($scope.reports)
  3. [some time later] the promise from ReportService.findAll() resolves and calls your success callback, which in turn sets $scope.reports = response.data.reports;

As you can see, it makes sense that when you call console.log in step 2, that your variable is undefined. So your variable is defined/populated in your controller, just not at the point in time when you call console.log($scope.reports).

Nikolaj Dam Larsen
  • 5,455
  • 4
  • 32
  • 45
  • Do i have to have the rest of my code under the then function? Was thinking it would be possible to use the scope.reports globally or outside the asynchronous call – Jude Mwenda Nov 08 '17 at 09:35
  • If you're doing something with the value of `$scope.reports` inside the controller, then yes, you must do it at the point in time that the `then` callback is executed. This is pretty much how asynchrony works in almost all programming languages and frameworks; you cannot manipulate the data until it's ready. You can use it in templates, just fine, since the dirty checking of angular, makes sure to update the view whenever the value of the variable changes. – Nikolaj Dam Larsen Nov 08 '17 at 09:43
0

By the time your service returning the response, console.log($scope.reports) is executing. Hence you are getting undefined

Please put your console statement inside .then(function success(){

It won't be an undefined and it will print the reports

Controller

.controller('MyViewController', [
'$scope', 'ReportService', 'toaster', '$modal', '$rootScope',
function ($scope, ReportService, toaster, $modal, $rootScope) {
    ReportService
        .findAll()
        .then(
        function success(response, status, headers, config) {
            $scope.reports = response.data.reports;
           console.log($scope.reports) // put it here // #2 won't be undefined.
        },
        function error(response, status, headers, config) {
            console.log('error');
        });
      //console.log($scope.reports) returns undefined here. //#2 remove from here
}
]);
Community
  • 1
  • 1
skdonthi
  • 1,308
  • 1
  • 18
  • 31