0

In my $scope.accept I'm trying to upload some files to my server, the script is working when I just do <form id="mForm" action="http://.php" method="post" enctype="multipart/form-data"> in my HTML.

But I want to stop the redirect, so I want to do it with ajax on my controller. When I run the same script in the controller side I get this error: TypeError: Cannot read property 'length' of undefined at subir ..... At this line particularly: var i = 0, len = filedata.files.length, img, reader, fil;

function subir() {
    alert("ok");
var filedata = document.getElementsByName("file"),
        formdata = false;
if (document.FormData) {
    formdata = new FormData();
}
var i = 0, len = filedata.files.length, img, reader, file;

for (; i < len; i++) {
    file = filedata.files[i];

    if (document.FileReader) {
        reader = new FileReader();
        reader.onloadend = function(e) {
            showUploadedItem(e.target.result, file.fileName);
        };
        reader.readAsDataURL(file);
    }
    if (formdata) {
        formdata.append("file", file);
    }
}

if (formdata) {
    $.ajax({
        url: "http:.php",
        type: "POST",
        dataType:'json',
        data: {json: formdata},
        processData: false,
        contentType: false,
        success: function(res) {                    
                alert("success");
        },       
        error: function(res) {
                alert("error");
         }       
         });
        }
    };

This is part of the HTML:

         <input type="file" accept="image/*;capture=camera" onchange="openFile_1(event)" id="file_1" class="custom-file-input" name="file[]">
     <img id="srcImage1" height="0">                                    
     </span>
        <span class="item item-input">                  
     <input type="text" id="obs_1" placeholder="Observaciones" style="text-align:left;"/>       
     </span>
        <span class="item item-input">
     <input type="file" accept="image/*;capture=camera" onchange="openFile_2(event)" id="file_2" class="custom-file-input" name="file[]">
Vega
  • 27,856
  • 27
  • 95
  • 103
1x2x3x4x
  • 592
  • 8
  • 26
  • As you did not add 'multiple' to your input tag for multiple files, may be that is why length property is not accessible – AkankshaGupta Jul 24 '17 at 15:29

2 Answers2

0

This line in your code returns an array of all the files that have been uploaded, even if it is only one file:

var filedata = document.getElementsByName("file")

Furthermore, when you try to access the property files of filedata, it returns undefined because the files property can only be obtained from an individual element in this array.

To fix it, try changing this line:

var i = 0, len = filedata.files.length, img, reader, file;

To this:

var i = 0, len = filedata[0].files.length, img, reader, file;

Additionally, you will need to change this line:

file = filedata.files[i];

To this:

file = filedata[0].files[i];

Or, if multiple files could be submitted, you could maybe even add a for loop that iterates through each file in filedata.

ajc2000
  • 651
  • 5
  • 20
0

You mentioned you're using AngularJS.

Here's one solution that you can try using angularjs

<input id="fileupload" type="file" name="files" file-model="myFile">

Here's file-model directive

.directive('fileModel', ['$parse', function ($parse) {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            var model = $parse(attrs.fileModel);
            var modelSetter = model.assign;
        }
    };
}]);

Here's how your controller code looks like

$scope.myFile = null;

You get file details/file in myFile variable but it is a array so while you pass it to service, you should write separate service like following

 this.uploadFile = function(file) {
            var fd = new FormData();
            fd.append('file', file[0]); 
// file[0] if you're passing myFile directly from controller otherwise you can pass myFile[0] from there and pass just file here
            var d = $q.defer();
            $http.post(uploadUrl, fd, {
                transformRequest: angular.identity,
                headers: {
                  'Content-Type': undefined
                }
              })
              .success(function(response) {
                d.resolve(response);
              })
              .error(function(response) {
                d.reject(response);
              });
             return d.promise;
        };

EDIT:

In your solution try this

var filedata = document.getElementsByName("file"),
     formdata = false;
     if (document.FormData) {
       formdata = new FormData();
     }
var i = 0, len = filedata.length, img, reader, file;

Your fileData is having all files so you don't need to do .files

Rakesh Chand
  • 3,105
  • 1
  • 20
  • 41