Tengo un servicio que utiliza una función de callback para pasar contenido a un controlador:
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 } })
Este servicio utiliza el módulo de nodo csvtojson para obtener contenido de un archivo csv como JSON. Y aquí está el controlador que lo usa:
angular.module('piApp').controller('homeController', ['$scope', 'dataRetrievalService', function ($scope, dataRetrievalService) { dataRetrievalService.getContents(function(contents) { $scope.result = contents; }); }]);
Me pregunto cómo movería correctamente la lógica de análisis a otro servicio que se inyecta en dataRetrievalService
y aún así obtendría el contenido del archivo csv en el controlador después de que se haya analizado.
Así que mi nuevo csvService
sería
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 } })
Y mi dataRetrievalService
convierte en algo así como
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 } }])
Me cuesta imaginar cómo funcionaría esto para pasar una segunda callback al controlador y aún así obtener el contenido deseado. ¿Cómo puedo pasar el contenido de servicio a servicio al controlador DESPUÉS de que se haya analizado?
Muchas gracias por tu tiempo. Avíseme si necesita información adicional o si no estoy seguro.
Esta pregunta es una extensión de este post anterior.
Esta es una buena idea para separar las rutinas de carga y análisis. Sin embargo, en lugar de callback es más conveniente usar promesas. Así es como se verían los servicios en este caso:
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; }); }]);