Search code examples
angularjsfunctionwaitvar

How to get var in global object after function complete


Have a function that's convert *.csv file to JSON. In function I can print this JSON to console.log console.log(jsonner); but I can't transfer it to Angular controller. $scope.names = jsonner; I have 2 problems: how wait fuction, and how makes var jsonner global.

function csvJSON(csv){

  var lines=csv.split("\n");
  var result = [];
  var headers=lines[0].split(",");

  for(var i=1;i<lines.length;i++){

      var obj = {};
      var currentline=lines[i].split(",");

      for(var j=0;j<headers.length;j++){
          obj[headers[j]] = currentline[j];
      }

      result.push(obj);

  }

  //return result; //JavaScript object
  return JSON.stringify(result); //JSON
}

function processFiles(files) {
    var file = files[0];
    var reader = new FileReader();
    reader.onload = function (e) {
    // Когда это событие активируется, данные готовы.
    // Вставляем их в страницу в элемент <div>
    var output = document.getElementById("fileOutput");   
    output.textContent = e.target.result;
    content = output.textContent;
    jsonner = csvJSON(content);
    console.log(jsonner);
};
    reader.readAsText(file);

}




var SearchApp = angular.module('SearchApp',[]);
 SearchApp.controller('ctrl2', ['$scope', function($scope){
    // Here the array would be your response.text:
    $scope.names = jsonner;

}]);

Solution

  • You're $scope.names is pointing to the original jsonner in memory. You're creating a new object with jsonner = csvJSON(content); because it returns the result array. You would have to modify the original array to get it to update the way you want.

    Here is a demo of the working logic to get you started: Plunker Demo

    Unfortunately file inputs don't work with ng-change, however there's a couple workarounds. You can do this:

    <input id="fileInput" type="file" ng-model="files" onchange="angular.element(this).scope().processFiles(this)">

    or you can wire up the event using element.on('change', processFiles) within a custom directive. Here's what I did:

    <body ng-controller="ctrl2">
      <input id="fileInput" type="file" ng-model="files" onchange="angular.element(this).scope().processFiles(this)">
      <div>{{ output }}</div>
    
      <div ng-repeat="todo in names track by $index" class="repeat">
          <div class="comname">{{todo.Name}}</div>
          <div class="price">{{todo.Price}}</div>
          <div class="change">{{todo.Change}}</div>
      </div>
    </body>
    

    and the logic:

    var SearchApp = angular.module('SearchApp', []);
    SearchApp.controller('ctrl2', ['$scope', function ($scope) {
        $scope.processFiles = function (element) {
          var file = element.files[0];
          var reader = new FileReader();
    
          reader.onload = function (e) {
            // Need to notify angular of this event using $apply
            $scope.$apply(function() {
              // Когда это событие активируется, данные готовы.
              // Вставляем их в страницу в элемент <div>
              var output = document.getElementById("fileOutput");
              $scope.output = e.target.result;
              jsonner = csvJSON(e.target.result);
              console.log(jsonner);
              $scope.names = jsonner;
            });
          };
    
          reader.readAsText(file);
        };
    
    
    }]);