0

I want upload the image or file with the tag html but I read that angularJs don't support this tag so the solution is to create a custom directive. So in my page index.html I wrote this code:

<body ng-controller="myController">
     <input type="file" file-model="myFile"/>
</body>

In my js file I write this code:

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


modulo.directive('fileModel', function() {
    var modulo = angular.module('myApp', []);
         return {
              restict: 'A',
              link: function (scope, element, attr) {

         }
 }

I don't uderstand how I can read the file that the user upload so I don't understand what write in the link function. How can I fix my problem? Is there anybody that help me? Thanks!

4

2 Answers 2

1

You can not read the file if your browser doesn't supports FileReader API.

Your directive is applied on a file upload control. So, you can listen to its change event. With this change event, you can extract the file object provided in event, emit an event to catch it the controller.

app.directive('fileUpload', function () {
return {
    scope: true, 
    link: function (scope, element, attrs) {
        /*Every time you select a file or a multiple files, change event is triggered. 
        So, with this on, we are attaching a listener event to it. This event also contains useful data. Like the array of selected files. 

        So, we iterate over the selected files, and emit an event containing file info.*/
        element.on('change', function (event) {
            var files = event.target.files;                
            for (var i = 0;i<files.length;i++) {

                scope.$emit("fileSelected", { file: files[i] });
            }                                       
        });
    }
};

With this code, you are listening to a file upload control's change event. On change, you are emitting an event called fileSelected, that you will receive in controller.

function DefaultController($scope){
      $scope.files = [];
      $scope.$on('fileSelected', function($event, args){
            $scope.files.push( args.file );
};

Please note that, with this code, you are only adding file objects in your scope. You still need to send a request to upload file.

You can use fallowing code taken from with a little bit of correction.

$http({
            method: 'POST',
            url: "/Api/PostStuff",
            headers: { 'Content-Type': undefined},
            transformRequest: function (data) {
                var formData = new FormData();

                formData.append("model", angular.toJson(data.model));

                for (var i = 0; i < data.files.length; i++) {                        
                    formData.append("file" + i, data.files[i]);
                }
                return formData;
            },                
            data: { model: $scope.model, files: $scope.files }
        }).
        success(function (data, status, headers, config) {
            alert("success!");
        }).
        error(function (data, status, headers, config) {
            alert("failed!");
        });
Sign up to request clarification or add additional context in comments.

15 Comments

Sorry can you comment this code? 1) element.on('change', function (event) 2) var files = event.target.files; Thanks
Added comment on the suggested line.
If i want upload one file one-by-one, i must write in this way? var file = event.target.files; scope.$emit("fileSelected", file);
No. If you want your file to be upload sequentially, it should be AJAX request that must be sent one by one containing one file at a time.
Sorry I wrote bad...I want send one file and don't send multi-file...the user can replace the file but he/she can send only one file
|
0

You may use already built modules. There are already many Angular.js modules to perform file uploading:

https://github.com/nervgh/angular-file-upload/
https://github.com/leon/angular-upload
https://github.com/danialfarid/angular-file-upload
https://github.com/uploadcare/angular-uploadcare

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.