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?

2
  • from the code you posted, it appears to be missing an ng-app declaration - put ng-app on the body tag like so: <body ng-app='myApp' ng-controller="myController"> Commented Apr 22, 2015 at 9:53
  • I omitted in this example because it is served Commented Apr 22, 2015 at 9:55

2 Answers 2

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

Sign up to request clarification or add additional context in comments.

2 Comments

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!
@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); };
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 />

1 Comment

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!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.