0

I have a list of names in a locally stored JSON file:

[
    {
        "SID": "ADYN"
    },
    {
        "SID": "ANGRYPIXEL"
    }
]

I have a service using $resource to successfully read the JSON file:

FrontEndApp.factory('readFileService', function ($resource) {
    return $resource('data/:file',{file: "@file"});
});

When just printing to the HTML view, the list of names works correctly. However, I want to use the names from the JSON file to then query an API. By using '.then', I can identify the number of names in the file, but not access the names themselves:

var query = readFileService.query({file: "orgList.json"});
query.$promise.then(function(data){
        $scope.orgData = data;

        //promise still not resolved??
        for(org in $scope.orgData){
            console.log(org);// prints 0 1 instead of objects
            console.log(org.SID);// undefined instead of ADYN ANGRYPIXEL
            //var results = getMembersService.get({orgName: org.SID});
            //results.$promise.then(function(results){
            //  for(result in results)$scope.orgDataArray.push(result.name);
            //});
        }
});

Should using '.then' not delay the rest of the code until the promise resolves? Since the JSON file is local, there's no possibility of failure. How do I stall my for loop until its promise resolves?

I tried using $scope.orgData = data.toJSON(); as recommended by several posts, but I get "Error: data.toJSON is not a function"

EDIT: Based on a suggestion, I tried console.log(data.data), which is undefined. console.log(data) shows an array of 331 objects, which it should because my full JSON file has 331 objects in it.

It gets interesting: when I tried data[0].SID, I got the first name! However, if I run for(org in data), it only works for the first org. Why?

As a workaround, I can print the objects using a loop counter:

var i = 0;
for(org in data){
                console.log(data[i]);
                i++;
}

Strangely, that prints out all 331 and then 2 more 'undefined'

EDIT2: Alright, so I got my app working with some nasty looking workaround code, except I get an error in the console when from 'i' incrementing too high (I'm guessing it includes a pair of promise objects). There's no way this is the "correct" way to handle data.

$scope.orgDataArray = [];

var query = readFileService.query({file: "orgList.json"});
query.$promise.then(function(data){
    $scope.orgData = data;
    console.log(data[0]);
        var i = 0;
        console.log(data.length);
        //promise still not resolved??
        for(org in data){
            //console.log(data[i].SID);
            var results = getMembersService.get({orgName: data[i].SID});
            results.$promise.then(function(res){
                var j=0;
                for(member in res.data){
                    //console.log(res.data[j].handle);
                    $scope.orgDataArray.push(res.data[j].handle);
                    j++;
                }
            });
            i++;
        }
});

EDIT3: Thanks Dinesh! So,

for(item in items)item.attribute doesn't work, but

for(item in items)items[item].attribute does, and that !isNaN got rid of the console error from trying to loop over promised/resolved

EDIT4: Final Code

FrontEndApp.controller('MemberController', ['$scope', '$http', 'readFileService', 'getMembersService', function($scope, $http, readFileService, getMembersService) {

    $scope.orgDataArray = [];

    var query = readFileService.query({file: "orgList.json"});
    query.$promise.then(function(data){
        $scope.orgData = data;

        for(var org in $scope.orgData){
            if(!isNaN(org)){//ignore promise and resolved
                var results = getMembersService.get({orgName: $scope.orgData[org].SID});
                results.$promise.then(function(apiObject){
                    for(member in apiObject.data){
                        $scope.orgDataArray.push(apiObject.data[member].handle);
                    }
                });//end members subquery
            }
        }
    });//end orgList query
}]);
Sabine
  • 11
  • 3
  • try this $scope.orgData = data.data; – Hadi J Apr 24 '16 at 18:06
  • Is `$scope.orgData` being assigned? If so, your promise is resolved. If not, then your promise is encountering an error when requesting the file. Try attaching a `.catch` to see if you're unknowingly hitting an exception (though Angular tends to be pretty loud about those..) – Dan Apr 24 '16 at 19:39
  • You seem to expect `data` to be an array? You should use a proper loop then, see [Why is using `for…in` on arrays such a bad idea?](https://stackoverflow.com/q/500504/1048572) – Bergi Apr 24 '16 at 20:31

1 Answers1

0

May be this plunker could help you out. With following code

 for(var org in $scope.orgData){
  //for loop will return the key of the $scope.orgData and that will be the array index
  if(!isNaN(org)){ //to ignore the $promise and $resolve objects from the data
    console.log($scope.orgData[org]);
    console.log($scope.orgData[org].SID);
  }
}
Dinesh Dabhi
  • 856
  • 1
  • 7
  • 18