Alessandro
Alessandro

Reputation: 925

Upload file/image with AngularJs

I want upload a file (so image) with AngularJs...I read the AngularJs don't support tag input type="file" so I read that I need of custom directive...I want fetch the input file and use it for show preview (thumbnail) on same page html and in controller upload the file on server...in my page html I wrote this code:

<body ng-controller="myController">

<h1>Select file</h1>
<input type="file" file-model="myFile" />
<div>
     <h2>File content is:</h2>
     <pre>{{ content }}</pre>
</div>

</body>

I wrote this directive:

var modulo = angular.module('myApp', []);


modulo.directive('fileModel', function () {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            element.on('change', function (event) {
                var file = event.target.files[0];
                scope.$emit("fileSelected", file);
            });            
        }
    };
});

And this is my controller:

modulo.controller('myController', function ($scope) {

    $scope.$on('fileSelected', function (event, args) {
        $scope.content(args.file);
        console.log(args.file);
    });
});

This code don't work...is there a solution? Where is the error?

Upvotes: 2

Views: 5009

Answers (2)

Angular Learner
Angular Learner

Reputation: 390

The error is in your directive

Check this ,i have used the same directive in my app

 .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 is my html to 
input(type="file", file-model="myFile", accept="image/*", image="image", id='fileInput')

This is a small service which I have created to handle the upload

function fileUpload (file, uploadUrl) { 

var cropedImage = dataURItoBlob(file);
var fileData = new FormData(),
    uploadedImage = '';
fileData.append('fileUpload', cropedImage);

return $http({
  withCredentials: true,
  method: "POST",
  url: uploadUrl,      
  data: fileData,
  headers: {'Content-Type': undefined},
  transformRequest: angular.identity
});    

}    

Try this, it's working for me

Upvotes: 1

Michael
Michael

Reputation: 3326

You should do the following for displaying the image:

<pre><img data-ng-src="data:image/png;base64,{{ content }}"/></pre>

And for retrieving the data from the input, you should use a custom directive such as shown in this answer:

angular.module('appFilereader', []).directive('appFilereader', function($q)   
{
    var slice = Array.prototype.slice;
    return {
       restrict: 'A',
       require: '?ngModel',
       link: function(scope, element, attrs, ngModel) {
            if (!ngModel) return;

            ngModel.$render = function() {};

            element.bind('change', function(e) {
                var element = e.target;

                $q.all(slice.call(element.files, 0).map(readFile))
                    .then(function(values) {
                        if (element.multiple) ngModel.$setViewValue(values);
                        else ngModel.$setViewValue(values.length ? values[0] : null);
                    });

                function readFile(file) {
                    var deferred = $q.defer();

                    var reader = new FileReader();
                    reader.onload = function(e) {
                        deferred.resolve(e.target.result);
                    };
                    reader.onerror = function(e) {
                        deferred.reject(e);
                    };
                    reader.readAsDataURL(file);

                    return deferred.promise;
     }

 ); //change

And in your html:

    <input type="file" ng-model="editItem._attachments_uri.image" 
accept="image/*" app-filereader />

Upvotes: 0

Related Questions