Join the Stack Overflow Community
Stack Overflow is a community of 6.6 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

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?

share|improve this question
    
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"> – oliveromahony Apr 22 '15 at 9:53
    
I omitted in this example because it is served – Ragnarr Apr 22 '15 at 9:55

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

share|improve this answer
    
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! – Ragnarr 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('ch‌​ange',handleFileSele‌​ct); 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); }; – Amruth Rao Apr 23 '15 at 6:52

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 />
share|improve this answer
    
Sorry but this code is all in directive??? – Ragnarr Apr 22 '15 at 9:56
    
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! – Ragnarr Apr 22 '15 at 10:52

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.