1

I'm populating $scope.master with data from a csv file. Within the function where I populate $scope.master, all of the data is there. See the log output; I put it in-line.

However, outside of the function, $scope.master is still populated with the data as expected, but console.log(Object.getOwnPropertyNames($scope.master)) returns an empty array, and console.log(Object.getOwnPropertyNames($scope.master).length) returns 0.

Why would the obviously non-empty $scope.master object return an empty array for its properties?

angular.module('app', []);
angular.module('app').controller('mainCntrl', ['$scope', 
function ($scope) {

  $scope.master = {}; 
  $scope.selected_interface = "";
  $scope.selected_DBCfile = "";
  $scope.DBCfiles = [];

  var CSV_filepath = '../data/interfaces.csv';

  d3.csv(CSV_filepath, function (err, data) {
    data.forEach(function (d) {
      d.interfaceName = d.interfaceName;
      d.DBCfile  = d.DBCfile;
      d.AtoB = +d.AtoB;
      d.BtoA = +d.BtoA;

      if (!$scope.master[d.interfaceName]) {
        var DBCfilesForInterface = {};
        DBCfilesForInterface[d.DBCfile] = new Array();
        DBCfilesForInterface[d.DBCfile].push(d);
        $scope.master[d.interfaceName] = DBCfilesForInterface;
      }
      else if (!$scope.master[d.interfaceName][d.DBCfile]) {
        $scope.master[d.interfaceName][d.DBCfile] = new Array();
        $scope.master[d.interfaceName][d.DBCfile].push(d);
      }
      else{
        $scope.master[d.interfaceName][d.DBCfile].push(d);
      }
    })

    //master is all made
    $scope.interfaces = Object.keys($scope.master);
    $scope.selected_interface = $scope.interfaces[0];
    $scope.DBCfiles = Object.keys($scope.master[$scope.selected_interface]);
    $scope.selected_DBCfile = $scope.DBCfiles[0];


//LOOK AT THESE LOGS
    console.log($scope.master);
    //Object { 1 - ModelS ESP 1.0 Interface: Object, 2 - ModelS ESP 2.0 Interface: Object, 3 - ModelS ESP 2.0 Interface with Tesla Body Controls: Object, 4 - ModelS ESP 2.0 Interface with Tesla Body Controls and TH bus: Object }

    console.log($scope.selected_interface);
    //"1 - ModelS ESP 1.0 Interface"

    console.log($scope.selected_DBCfile);
    //"ModelS_BDY.dbc"

    console.log($scope.DBCfiles);
    //Array [ "ModelS_BDY.dbc", "ModelS_BFT.dbc", "ModelS_CH.dbc", "ModelS_ETH.dbc", "ModelS_OBDII.dbc", "ModelS_PT.dbc", "ModelX_TH_common.dbc" ]

  });

//OUTSIDE OF THE FUNCTION
    console.log($scope.master);
    //Object { 1 - ModelS ESP 1.0 Interface: Object, 2 - ModelS ESP 2.0 Interface: Object, 3 - ModelS ESP 2.0 Interface with Tesla Body Controls: Object, 4 - ModelS ESP 2.0 Interface with Tesla Body Controls and TH bus: Object }
    //$scope.master has data, as expected

    console.log(Object.getOwnPropertyNames($scope.master));
    //Array [  ]
    //however, it has no properties? but we just saw them in the above log...

    console.log(Object.getOwnPropertyNames($scope.master).length);
    //0

    console.log($scope.selected_interface);
    //""
    //this has suddenly turned empty as well

    console.log($scope.selected_DBCfile);
    //""
    //this has suddenly turned empty as well

    console.log($scope.DBCfiles);
    //Array [  ]
    //this has suddenly turned empty as well

}]);
user2946797
  • 171
  • 2
  • 11
  • This seems to be the same problem as [How to return the response from an asynchronous call?](http://stackoverflow.com/q/14220321/1529630) – Oriol Jul 14 '15 at 18:52

1 Answers1

2

This happens because d3.csv is an async method.

All the consoles outside the function run before data is finished paring and storing into the variables. Place all your methods processing of the file data into the callback of the d3.csv method and they should get all the values populated into them once data is parsed and available.

Hope this helps.

Alex_B
  • 838
  • 7
  • 13