Tavant Logo

Handling image uploads with AngularJS

Share to

When developing web applications, one of the common use cases  would be to manage image uploads along with validations for supported formats and sizes. Here, we outline a way to achieve this in AngularJS using a file reader service.

File reader module

This module is intended for common usage across all screens where there is requirement to read the file. You can include the following code in a file upload.js

(function (module) {

 

var fileReader = function ($q, $log) {

 

var onLoad = function(reader, deferred, scope) {

return function () {

scope.$apply(function () {

deferred.resolve(reader.result);

});

};

};

 

var onError = function (reader, deferred, scope) {

return function () {

scope.$apply(function () {

deferred.reject(reader.result);

});

};

};

 

var onProgress = function(reader, scope) {

return function (event) {

scope.$broadcast(“fileProgress”,

{

total: event.total,

loaded: event.loaded

});

};

};

 

var getReader = function(deferred, scope) {

var reader = new FileReader();

reader.onload = onLoad(reader, deferred, scope);

reader.onerror = onError(reader, deferred, scope);

reader.onprogress = onProgress(reader, scope);

return reader;

};

 

var readAsDataURL = function (file, scope) {

var deferred = $q.defer();

 

var reader = getReader(deferred, scope);

reader.readAsDataURL(file);

 

return deferred.promise;

};

return {

readAsDataUrl: readAsDataURL

};

};

module.factory(“fileReader”,

[“$q”, “$log”, fileReader]);

 

}(angular.module(“App”)));

Update the value ‘App’ with the name of your app in the last line of the above code.

Image reading and Validation

Define a directive called ‘ngFileSelect’ to validate the image for supported formats, size and dimension.

App.directive(“ngFileSelect”,function(){

return {

link: function($scope,el){

el.on(‘click’,function(){

this.value = ”;

});

el.bind(“change”, function(e){

$scope.file = (e.srcElement || e.target).files[0];

 

var allowed = [“jpeg”, “png”, “gif”, “jpg”];

var found = false;

var img;

img = new Image();

allowed.forEach(function(extension) {

if ($scope.file.type.match(‘image/’+extension)) {

found = true;

}

});

if(!found){

alert(‘file type should be .jpeg, .png, .jpg, .gif’);

return;

}

img.onload = function() {

var dimension = $scope.selectedImageOption.split(” “);

if(dimension[0] == this.width && dimension[2] == this.height){

allowed.forEach(function(extension) {

if ($scope.file.type.match(‘image/’+extension)) {

found = true;

}

});

if(found){

if($scope.file.size <= 1048576){

$scope.getFile();

}else{

alert(‘file size should not be grater then 1 mb.’);

}

}else{

alert(‘file type should be .jpeg, .png, .jpg, .gif’);

}

}else{

alert(‘selected image dimension is not equal to size drop down.’);

}

};

img.src = _URL.createObjectURL($scope.file);

 

});

}

};

});

If the image is valid, the directive calls ‘getFile’ function to get the base64 url of the image for preview, as defined below.

 

$scope.getFile = function () {

var dimension = $scope.selectedImageOption.split(” “);

fileReader.readAsDataUrl($scope.file, $scope)

.then(function(result) {

$scope.imagePreview = true;

$scope.upladButtonDivErrorFlag = false;

$(‘#uploadButtonDiv’).css(‘border-color’,’#999′);

$scope.imageSrc = result;

var data = {

“height”: dimension[2],

“weight”: dimension[0],

“imageBean”: {

“imgData”: result,

“imgName”: $scope.file.name

}

}

$scope.imagePreviewDataObject = data;

});

}

 

Finally, you can bind the directive to your input button, in html, as follows:

<span class=”btn btn-default btn-file” ng-class=’class1′>

Upload Image <input type=”file” ng-file-select=”onFileSelect($files)” accept=”.jpg,.png,.gif,.jpeg”>

</span>

PS: File reader module works correctly in all modern browsers. For IE, it was found to support version 11 onwards.

 

Tags :

Let’s create new possibilities with technology