How to Upload Multiple Files in AngularJS Using Web API

In this article, we will learn how to upload multiple files in AngularJS Using Web API

Create Angular Project

Now let’s create an Angular Project by using the following command,

ng new UploadMultipleFiles

Now open the newly created project in visual studio code and install bootstrap by using the following command

npm install bootstrap --save

Now open styles.css file and add Bootstrap file reference. To add reference in styles.css file add this line.

@import '~bootstrap/dist/css/bootstrap.min.css';

AngularJS View

<!DOCTYPE html>
<html>
<head>
  <title>File Upload Example in AngularJS</title>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.min.js"></script>
</head>

<body ng-app="fupApp">

    <div ng-controller="fupController">
        <input type="file" id="file" name="file" multiple
            onchange="angular.element(this).scope().getFileDetails(this)" />

        <input type="button" ng-click="uploadFiles()" value="Upload" />

        <!--ADD A PROGRESS BAR ELEMENT.-->
        <p><progress id="pro" value="0"></progress></p>
    </div>

</body>

The angular.element() method is an interface between jQuery and AngularJS. Angular says, “use this method if you are not using jQuery in your application”. Therefore, when you select files, the angular.element calls the function defined in the scope.

The Controller and the Scope

<script>
    var myApp = angular.module('fupApp', []);

    myApp.controller('fupController', function ($scope) {

        // GET THE FILE INFORMATION.
        $scope.getFileDetails = function (e) {

            $scope.files = [];
            $scope.$apply(function () {

                // STORE THE FILE OBJECT IN AN ARRAY.
                for (var i = 0; i < e.files.length; i++) {
                    $scope.files.push(e.files[i])
                }

            });
        };

        // NOW UPLOAD THE FILES.
        $scope.uploadFiles = function () {

            //FILL FormData WITH FILE DETAILS.
            var data = new FormData();

            for (var i in $scope.files) {
                data.append("uploadedFile", $scope.files[i]);
            }

            // ADD LISTENERS.
            var objXhr = new XMLHttpRequest();
            objXhr.addEventListener("progress", updateProgress, false);
            objXhr.addEventListener("load", transferComplete, false);

            // SEND FILE DETAILS TO THE API.
            objXhr.open("POST", "/api/fileupload/");
            objXhr.send(data);
        }

        // UPDATE PROGRESS BAR.
        function updateProgress(e) {
            if (e.lengthComputable) {
                document.getElementById('pro').setAttribute('value', e.loaded);
                document.getElementById('pro').setAttribute('max', e.total);
            }
        }

        // CONFIRMATION.
        function transferComplete(e) {
            alert("Files uploaded successfully.");
        }
    });
</script>
</html>

Function getFileDetails() inside the controller, takes a single parameter. This function is called when, you select files using the <input> file type, from the application view. The parameter has the elements information, such as, file type, number of files, names etc. Later, we will store each file’s information in an array.

The second method uploadFiles() is called when the user clicks the upload button.

$scope.uploadFiles = function ()

To upload the files, first I am using FormData() object to collect the file details from the array $scope.files[]. Once I have extracted the details, I’ll make a call to the Web API for upload. To do this I am using XMLHttpRequest. This is one of simplest method to make http requests, using both GET and POST. Here, however I have to make a POST request, since I am sending file to the server to upload.

Before sending the data for processing, I have added two listeners, one for the progress of the file upload and the other a confirmation when it’s done.

objXhr.addEventListener("progress", updateProgress, false); //FOR PROGRESS.
objXhr.addEventListener("load", transferComplete, false); //FOR CONFIRMATION.

To show the progress, I have added an HTML5 <progress> element in the markup section. In the controller, I have declared a function that will update the progress for every byte it transfers.

The first listener (for progress) calls the updateProgress() function and receives values in bytes. I am assigning the values to <progress> elements two attributes, that is, value and max.

function updateProgress(e) {
    if (e.lengthComputable) {
        document.getElementById('pro').setAttribute('value', e.loaded);
        document.getElementById('pro').setAttribute('max', e.total);
    }
}

 

Submit a Comment

Your email address will not be published.

Subscribe

Select Categories