How to pass content from service to another service to controller with callbacks after it has been parsed?

I have a service that uses a callback function to pass content to a controller:

  angular.module('piApp').service("dataRetrievalService", function () {

  function getContents(callback) {
      //Converter Class 
      var fs = require("fs");
      var Converter = require("csvtojson").Converter;
      var fileStream = fs.createReadStream("order.csv");
      //new converter instance 
      var converter = new Converter({ constructResult: true });
      //end_parsed will be emitted once parsing finished 
      converter.on("end_parsed", function (jsonObj) {
          console.log(jsonObj); //here is your result json object 
          //getResult(jsonObj)
          callback(jsonObj);
      });
      //read from file 
      fileStream.pipe(converter);
  }

  // public api
  return {
      getContents: getContents
  }
})

This service uses the csvtojson node module to get content from a csv file as JSON. And here is the controller that uses it:

angular.module('piApp').controller('homeController', ['$scope', 'dataRetrievalService', function ($scope, dataRetrievalService) {

     dataRetrievalService.getContents(function(contents) {
     $scope.result = contents;
     });

}]);

I'm wondering how I would properly move the parsing logic to another service that is injected into dataRetrievalService and still get the contents of the csv file to the controller after it has been parsed.

So my new csvService would be

angular.module('piApp').service("csvService", function () {
// public methods

function getCsvAsJSON(callback) {
    //Converter Class 
    var fs = require("fs");
    var Converter = require("csvtojson").Converter;
    var fileStream = fs.createReadStream("Contents/Product Groups/orderTest2.csv");
    //new converter instance 
    var converter = new Converter({ constructResult: true });
    //end_parsed will be emitted once parsing finished 
    converter.on("end_parsed", function (jsonObj) {
        console.log(jsonObj); //here is your result json object 
        callback(jsonObj);
    });
    //read from file 
    fileStream.pipe(converter);
}


// public api
return {
    getCsvAsJSON: getCsvAsJSON
}
})

And my dataRetrievalService becomes something like

angular.module('piApp').service("dataRetrievalService", ['csvService', function (csvService) {

    function getContents() {

        csvService.getContents(function (contents) {
            this.result = contents; //should I be using another callback here instead?
        });
    }
    // public api
    return {
        getContents: getContents
    }
}])

I'm struggling to picture how this would work so that I pass a second callback to the controller and still get the desired content. How can I I pass the content from service to service to controller AFTER it has been parsed?

Thank you very much for your time. Let me know if you need any additional information or if I am being unclear.

This question is an extension of this previous post

Answers:

Answer

This is good idea to separate loading and parsing routines. However, instead of callback it's more convenient to use promises. This is how services could look like in this case:

angular.module('piApp').service("csvService", function($q) {

    // public methods
    function getCsvAsJSON() {
        var deferred = $q.defer();
        var fs = require("fs");
        var Converter = require("csvtojson").Converter;
        var fileStream = fs.createReadStream("Contents/Product Groups/orderTest2.csv");
        var converter = new Converter({constructResult: true});
        converter.on("end_parsed", function(jsonObj) {
            deferred.resolve(jsonObj);
        });
        fileStream.pipe(converter);
        return deferred.promise;
    }

    return {
        getCsvAsJSON: getCsvAsJSON
    }
});

angular.module('piApp').service("dataRetrievalService", ['csvService', function(csvService) {

    function getContents() {
        return csvService.getCsvAsJSON();
    }

    return {
        getContents: getContents
    }
}]);

angular.module('piApp').controller('homeController', ['$scope', 'dataRetrievalService', function ($scope, dataRetrievalService) {

    dataRetrievalService.getContents().then(function(contents) {
        $scope.result = contents;
    });

}]);

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.