0

I have created a CSV reader using https://github.com/bahaaldine/angular-csv-import as a reference. It currently looks like this:

.directive('csvReader', [function () {

    // Function to convert to JSON
    var convertToJSON = function (content) {

        // Declare our variables
        var lines = content.csv.split('\n'),
            result = [],
            headers = lines[0].split(content.separator),
            columnCount = lines[0].split(content.separator).length;

        // For each row
        for (var i = 1; i < lines.length; i++) {

            // Declare an object
            var obj = {};

            // Get our current line
            var line = lines[i].split(new RegExp(content.separator + '(?![^"]*"(?:(?:[^"]*"){2})*[^"]*$)'));

            // For each header
            for (var j = 0; j < headers.length; j++) {

                // Populate our object
                obj[headers[j]] = line[j];
            }

            // Push our object to our result array
            result.push(obj);
        }

        // Return our array
        return result;
    };

    return {
        restrict: 'A',
        scope: {
            result: '=',
            separator: '=',
            callback: '&saveResultsCallback'
        },
        link: function (scope, element, attrs) {

            // Create our data model
            var data = {
                csv: null,
                separator: scope.separator || ','
            };

            // When the file input changes
            element.on('change', function (e) {

                // Get our files
                var files = e.target.files;

                // If we have some files
                if (files && files.length) {

                    // Create our fileReader and get our file
                    var reader = new FileReader();
                    var file = (e.srcElement || e.target).files[0];

                    // Once the fileReader has loaded
                    reader.onload = function (e) {

                        // Get the contents of the reader
                        var contents = e.target.result;

                        // Set our contents to our data model
                        data.csv = contents;

                        // Apply to the scope
                        scope.$apply(function () {

                            // Our data after it has been converted to JSON
                            scope.result = convertToJSON(data);

                            // Call our callback function 
                            scope.callback(scope.result);
                        });
                    };

                    // Read our file contents
                    reader.readAsText(file);
                }
            });
        }
    };
}])

My HTML looks like this:

<div class="form-group">
    <label class="control-label">CSV file</label>
    <input type="file" csv-reader result="csv.results" save-results-callback="controller.saveResults(something)" />
</div>

<div class="block right" ng-if="controller.results">
    <h2>JSON</h2>
    <div class="content">{{ csv.results }}</div>
</div>

When I pick my CSV file, the contents are displayed on my view correctly. Now I wish to take them contents and save them to my database, but I can not get it to work properly. I was hoping that if I changed my csv.results to controller.results I would be able to access the results in my controller (I am using controllerAs and specifying "controller" as the name) but I just get undefined.

You can see I have tried adding a callback function but this doesn't work either.

Does anyone know how to solve my problem?

1
  • what is controllerAs? What about controller.csv.results ? Commented Apr 29, 2015 at 23:20

1 Answer 1

3

This was actually easier than I thought. Basically in my controller I specify a holder variable (self.results = []) and then I pass that to the directive. The directive then populates that with the formatted JSON and 2 way binding handles the rest.

Incase anyone else needs to know, here is what I did. I set up my controller like this:

.controller('ImportCollectionsController', ['$stateParams', 'UploadService', function ($stateParams, service) {

    // Assign this to a variable
    var self = this;

    // Used to validate the imported data
    self.validateResults = function (results) {

        // Validate our results
        var errors = service.validateImport(results);

        // If there are no errors
        if (errors.length === 0) {

            // Set our results object to our results
            self.results = results;
        } else {

            // Otherwise, display our errors
            self.errors = errors;
        }
    };

    // Save our data
    self.save = function () {

        // Log our results to make sure we actually have some
        console.log(self.results);

        // --- omitted for brevity --- //
    };
}]);

And my HTML looks like this:

<div class="form-group" ng-hide="controller.results">
    <label class="control-label">CSV file</label>
    <input type="file" csv-reader complete="controller.validateResults(results)" />
</div>

<div class="block right" ng-if="controller.results.length">
    <h2>JSON</h2>

    <div class="content">{{ controller.results }}</div>

    <div class="form-group">
        <button class="btn btn-primary" ng-click="controller.save()">Import</button>
    </div>
</div>

When the button is clicked, it calls controller.save() which in turn displays the array of json objects. Here is my directive just to complete this answer:

.directive('csvReader', [function () {

    // Function to convert to JSON
    var convertToJSON = function (content) {

        // Declare our variables
        var lines = content.csv.replace(/[\r]/g, '').split('\n'),
            headers = lines[0].split(content.separator),
            results = [];

        // For each row
        for (var i = 1; i < lines.length - 1; i++) {

            // Declare an object
            var obj = {};

            // Get our current line
            var line = lines[i].split(new RegExp(content.separator + '(?![^"]*"(?:(?:[^"]*"){2})*[^"]*$)'));

            // For each header
            for (var j = 0; j < headers.length; j++) {

                // Populate our object
                obj[headers[j]] = line[j];
            }

            // Push our object to our result array
            results.push(obj);
        }

        // Return our array
        return results;
    };

    return {
        restrict: 'A',
        scope: {
            results: '=',
            separator: '=',
            complete: '&'
        },
        link: function (scope, element) {

            // Create our data model
            var data = {
                csv: null,
                separator: scope.separator || ','
            };

            // When the file input changes
            element.on('change', function (e) {

                // Get our files
                var files = e.target.files;

                // If we have some files
                if (files && files.length) {

                    // Create our fileReader and get our file
                    var reader = new FileReader();
                    var file = (e.srcElement || e.target).files[0];

                    // Once the fileReader has loaded
                    reader.onload = function (e) {

                        // Get the contents of the reader
                        var contents = e.target.result;

                        // Set our contents to our data model
                        data.csv = contents;

                        // Apply to the scope
                        scope.$apply(function () {

                            // Our data after it has been converted to JSON
                            var results = convertToJSON(data);

                            // If we have a callback function
                            if (scope.complete) {

                                // Execute our callback
                                scope.complete({ results: results });
                            }
                        });
                    };

                    // Read our file contents
                    reader.readAsText(file);
                }
            });
        }
    };
}])

I hope this helps someone else.

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

1 Comment

Have you used only this code to make it working ? or have u added any other pat too ?

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.