0

I have to combine the data from three different sources. Ideally, I would do this on the web server, but I have to use JSON text files at this time until others are prepared to support the web service calls. As such, I have 3 JSON files that I need to loop through, and process the data for a page.

My problem is that the one structure I am getting initially, is not available later in my controller to process the data in. I know this should be moved to different controllers, and likely use factories/services, but I am trying to do a Proof of Concept to demo the available look/presentation to get approval to build the application. As such, quick and dirty is needed to simply get the approval for us to then break it and do it proper, with testing built in from the start.

My code:

var App = angular.module('App', []);

App.controller('Ctrl', function ($scope, $http)
{
    $scope.ToPlay = 0;
    $scope.Won    = 0;
    $scope.Lost   = 0;

    var Structure = [ "Col1", "Col2", "Col3" ];

    $scope.Data  = [];
    $scope.JSON1 = [];
    $scope.JSON2 = [];
    $scope.JSON3 = [];

    // Read the 3 files for processing
    $http.get('Data/JSON1.json').success(function(data) {
        $scope.JSON1 = data;
    });

    $http.get('Data/JSON2.json').success(function(data) {
        $scope.JSON2 = data;
    });

    $http.get('Data/JSON3.json').success(function(data) {
        $scope.JSON3 = data;
    });

    // Create Structure in Result
    var Headers = [];
    for( var i = 0; i < Structure.length; i++)
    {
        // Get the Value from Stucture for Columns
        Headers.push(Structure[i]);
    }
    $scope.Data[0] = [];
    $scope.Data[0].push(Headers);

    // Get Key from JSON1 ID Field for Each Row
    // Length of JSON1 is now 0 - This is the error
    for( var i = 0; i < $scope.JSON1.length; i++)
    {
        var Key = $scope.JSON1[i].Id;
        $scope.Data[Key] = [];
    }

    // Get Key from JSON2 Key Field for Each Row matches ID from JSON1
    for( var i = 0; i < $scope.JSON2.length; i++)
    {
        var Record = $scope.JSON2[i];
        $scope.Data[Record.Key].push({ "Date1": Record.Data1} );
    }

});

1 Answer 1

2

The fundamental issue is that you're making asynchronous requests and then trying to operate on their returns synchronously. At the point where you're attempting to access it, the return data has not yet arrived.

The $q library will help you to solve that problem as well as the one you're asking about. You can use $q.all to wait for all three responses before working with the returned data.

Example:

.controller('MyController', function($scope, $http, $q){
  var JSON1 = $http.get('example1.json');
  var JSON2 = $http.get('example2.json');
  var JSON3 = $http.get('example3.json');

  $q.all([JSON1, JSON2, JSON3]).then(function(results){
    $scope.combined = [];
    angular.forEach(results, function(result){
      $scope.combined.push(result.data);
    });
    // Data set to scope var and will appear in view
    // Do whatever else you need to with the data here now that it has arrived
  })
})

Demo

It's important that you access the data from inside of the then callback, which will fire once all three requests have returned.

This solution does not handle errors / rejected promises, but you asked for quick and dirty. Plus, there are plenty of resources out there to help you learn more about promises.

AngularJS $q docs

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for the response. I am having some problems though and I think it is going to be me, as your example looks pretty clear. I have updated a plunkr with my sample: plnkr.co/edit/gEJoX3s1FDxVmzgiWeMO?p=preview
Check out the code I commented in this Plunker.
Thanks alot, that helped me to understand the problem. Now I can work with the code, and get error handling etc... Thanks again for your help.
Did you notice that the Ids[] array did not get used though? The Name was never printed.
Typo in example1.json "id" -> "Id": plnkr.co/edit/DE8m7Vtl0FFdPkfvzQxF?p=preview
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.