2

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?

Alessandro
  • 905
  • 3
  • 17
  • 32

2 Answers2

1

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

Michael
  • 3,308
  • 5
  • 24
  • 36
Angular Learner
  • 390
  • 4
  • 16
  • Sorry can you comment the code? Also How can I pass the file/imge from directive to controller for show a preview of image? Thanks! – Alessandro Apr 22 '15 at 13:59
  • @user3751473 I have used the following to pass the file/image from directive to my controller function angular.element(document.querySelector('#fileInput')).on('change',handleFileSelect); my controller var handleFileSelect=function(selectedFile) { $scope.showCropSection = true; var file = selectedFile.currentTarget.files[0]; var reader = new FileReader(); reader.onload = function (selectedFile) { $scope.$apply(function($scope){ $scope.myImage = selectedFile.target.result; }); }; reader.readAsDataURL(file); }; – Angular Learner Apr 23 '15 at 06:52
0

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 />
Community
  • 1
  • 1
Michael
  • 3,308
  • 5
  • 24
  • 36
  • Sorry can you help me with my code? Because it must run...if i position un allert in directi in this way alert(file); I obtain [object File] so I fetch the file and I can read the name,size and last modified. When I pass the file with scope.$emit("fileSelected", file); I take this value in my controller...if I try to show the file in my page html and in my console I obtain in my console "undefined"....why? Thanks! – Alessandro Apr 22 '15 at 10:52