티스토리 뷰

Recently, I wrapped up the development of a directory page at work, and I learned so much from this project. The project entailed a multitude of tasks—fetching data from an API, implementing sorting and searching functionalities, importing and validating CSV files, and updating the API through POST requests for CRUD operations. While these features might appear straightforward on the surface, diving deeper reveals a complex web of interconnected components. 

Since this project was such a rich learning experience, I've decided to document it for both reflection and future reference. In my previous posts, we explored how to convert JSON data to a CSV file and enable its download.

Today, we're going to delve into the process of importing CSV files, mapping their data fields—such as Email, Title, and Phone—and then saving them using AngularJS's `$http.post`. And in the next post, we will talk about validating the data before making the POST request to update the API.

 

Creating a Custom Directive for File Input in AngularJS.

Before we get into the code, it's worth noting that AngularJS doesn't offer a native directive for file input handling. We'll need to create our own custom directive to bridge the gap between raw file input and AngularJS.


Here's a directive called `fileModel`, which leverages `$parse` to bind the file input to a scope variable:

.directive('fileModel', ['$parse', function ($parse) {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            var model = $parse(attrs.fileModel);
            var modelSetter = model.assign;

            element.bind('change', function () {
                scope.$apply(function () {
                    modelSetter(scope, element[0].files[0]);
                });
            });
        }
    };
}])

 

This directive ensures that any file input element in our HTML can bind to a scope variable, making it available for our AngularJS code to process.

 

Importing and Mapping CSV Data

In your controller, you can define a function named `$scope.importCSV`. This function will do the heavy lifting of reading the file, breaking it into lines and headers, and mapping these to JSON objects.

$scope.importCSV = function () {
    // Get the file from scope, populated by our 'fileModel' directive
    let file = $scope.myFile;
    if (file) {
        // Create a FileReader object
        let reader = new FileReader();
        
        // Define what happens when the file has been read
        reader.onload = function (event) {
            let contents = event.target.result;
            let lines = contents.split('\n');
            let headers = lines[0].split(',');
            let csvItems = [];

            // Loop through each line in the file
            let i = 1;
            while (i < lines.length) {
                let result = getNextRow(lines, i);  // Assume getNextRow is a function that gets the next row
                let row = result.row;
                i = result.nextIndex;

                // Skip empty lines
                if (row.join('').trim() === "") continue;

                let obj = {};
                // Loop through each header and assign the corresponding value to our object
                for (let j = 0; j < headers.length; j++) {
                    obj[headers[j].trim()] = row[j] ? row[j].trim() : "";
                }
                csvItems.push(obj);
            }

            // Map these objects to your desired format
            let allItems = [];
            for (let csvItem of csvItems) {
                let item = {
                    Id: generateId(),  // Assume generateId is a function that generates an ID
                    FirstName: csvItem["First Name"],
                    LastName: csvItem["Last Name"],
                    Email: csvItem["Email"]
                    // Add more fields as necessary
                };

                allItems.push(item);
            }

            // Save these objects by calling a function to do an HTTP POST operation
            $scope.saveCSV(allItems);
        };
        
        // Initiate reading the file
        reader.readAsText(file);
    }
};

 

This function is triggered when you want to import a CSV. It reads the file, iterates through the lines, and maps them to a list of JavaScript objects (`allItems`). Finally, it calls `$scope.saveCSV(allItems)` to save these objects.

 

Saving the Data

Finally, the `$scope.saveCSV` function is called to save this mapped data:

$scope.saveCSV = function (allItems) {
    return $http.post('/api/YourEndpoint/', {
        Data: JSON.stringify(allItems)
    });
};

 

This function posts the mapped JSON data to the API, where it's stored for future CRUD operations.

And that's a wrap for this installment! We've gone through the entire process of importing a CSV file, parsing its contents, and saving it to our API using AngularJS's $http.post. In the next post, we'll discuss how to validate this data before we hit that "Save" button and send it to our API. Until then, happy coding!