danialfarid / ng-file-upload

Lightweight Angular directive to upload files with optional FileAPI shim for cross browser support

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

there is only one file in $_FILES when uploading multiple files

fxck opened this issue · comments

commented

eventhough I'm trying it on the latest chrome, any idea where the problem could be?

                $scope.doSubmit = function() {

                        $upload
                            .upload( {
                                url: '/api/send-fellowship',
                                data: $scope.form,
                                file: $scope.form.files
                            })
                            .progress(function(e) {
                                $scope.progress = parseInt(100.0 * e.loaded / e.total);
                            })
                            .success(function(data, status) {

                            });
                };

$scope.form.files is an array of files

post your html here too

commented

@danialfarid

                        <button
                            class="form__file"
                            type="button"
                            ng-file-select
                            multiple="true"
                            ng-model="form.files">
                            Select file
                        </button>
commented

$scope.form.files
image

$_FILES
image

I'm facing the same situation. Don't know if it's related to #1 (comment) that data cannot be transferred along with multiple files.

you know that the file will not be sent with data: $scope.form, so just remove this or add specific values in your form that you want to actually send or remove the file object from it before sending it. The file should be specified in the 'file option not data.

commented

The file is specified in file option, with $scope.form.files, there are other things in $scope.form, like email and name, how could $scope.form.files value specified in both data and file break this?

Even if I don't write data field, the server script (PHP) still only receives one file data.
But I think Danial's suggestion is right. It's not a good practice to send multiple files along with data when you have to use a loop to upload files one by one. The better solution is separating the file uploading with the form input data submitting, uploading files immediately, and sending back the uploaded information to the frontend, where you can combine the uploaded information with form input data.

commented

Wait what, you have to use the loop to be able to upload multiple files? Also uploading files immediately is just anti-ux.

For older browsers IE9 you need to upload files one by one.

commented

Yeah, alright, not using any IE.

I'm facing the same situation here. Only one file makes it through to my upload controller, even though two or more files were actually selected. I don't have any interest in supporting IE9– anymore, so that's why I was investigating the "array of files" method which was much more intuitive to me.

@fxck did you have any success with this issue ?

commented

Yeah I switched to https://blueimp.github.io/jQuery-File-Upload/angularjs.html which is not ideal, I don't like their angular implementation at all.. but better than nothing.

Have you tried setting the option fileFormDataName: 'file[]' or fileFormDataName: ['file[0]', 'file[1]', 'file[2]', ...]

I just tried it yesterday after leaving my comment (found a Stack Overflow answer suggesting this), and it seems to work (even though I'm not really sure how I was supposed to use this). Thanks for your answer. I chose to use the second syntax (fileFormDataName: [ 'file[0]', 'file[1]' ]), was having issues with the other one.

@fxck did you try setting this parameter ?

I am closing this issue. Reopen if fileFormDataName: [ 'file[0]', 'file[1]' ] doesn't fix your problem.

Just to have a feedback for you people, this actually works. The way I made with a dynamic array was:

        var names = [];
        for (var i = files.length - 1; i >= 0; i--) 
            names.push(files[i].name);

        files.upload = $upload.upload({
            url: API_BASEURL + '/photo' + $scope.getReqParams(),
            method: 'POST',
            fileFormDataName: names,
            file: files
        });

Attention: increasing max file size in the server would save you lots of troubles.
PHP does not report errors like this, and it turns to an annoying-mysterious bug.

php.ini - default:

upload_max_filesize = 2M

  • 2M is less than the average size of smart phone camera picture.

For IE9, where does the limitation "one file at a time" come from ?
In the FileAPI documentation, it looks like it should be able to upload multiple files in IE with Flash: "Support - Multiupload: all browsers that support HTML5 or Flash"

If there is really nothing to be done to bypass this limitation, shouldn't it be specified in the "Old browsers known issues" documentation part ?

I have 2 file upload controls in my form, it means that I don't want to use same file upload control to upload multiple files.
I want separate control to upload single file from each.

Now please tell me how to handle this situation..?

@kishor10d just don't add multiple or ngf-multiple to the element and it would just let you select one file.

@danialfarid : Actually I have 2 file upload controls in my form and according to the ng-file-upload plugin, it can handle only one file upload control in a form(for single file or multiple files).
From one control, I want to upload an image & from other I want to upload a pdf.
So how can I handle this..?

What is ng-upload plugin? Are you sure you are on the correct github module?

@danialfarid : sorry, I MISS the middle word. Its ng-file-upload.. I corrected that in my previous comment.
Ok.. But is there any solution for this..?

commented

@rcbytes solution works!
But it has one problem when file name duplication exists.
it means that ,
if files[i].name is same '1.png' for all file, names will be ['1.png', '1.png' ... , '1.png']
In PHP, print_r($_FILES); shows that only $_FILES['1.png'] exists.

Solution :
add index prefix to name i + "_" +

    var names = [];
    for (var i = files.length - 1; i >= 0; i--) 
        names.push(i + "_" + files[i].name);

    files.upload = $upload.upload({
        url: API_BASEURL + '/photo' + $scope.getReqParams(),
        method: 'POST',
        fileFormDataName: names,
        file: files
    });

Thanks for @rcbytes solution.

@danialfarid
With the new version the fix don't work... because it force the "file" name of the field...
Also, don't work with the key,value pairs of the files in the file option.

If i try the older version, with the fileFormDataName, i have this error (from angular):

Error: Failed to execute 'setRequestHeader' on 'XMLHttpRequest': 'function (xhr) {.....

Well nothing worked from the above.
The problem is the name that the js object is made.
All have the key "File" so you lose information when you upload it to PHP.

I "reindexed" in a new array in order to "lose" the key.
So the solution for me was:

        filesMulti = {};
        for (var i = files.length - 1; i >= 0; i--){
             filesMulti[i]=files[i];
        }

        Upload.upload({
            url: '/upload.php',
            method: 'POST',
            sendFieldsAs: 'form',
            fields: {},
            file: filesMulti
        })

I found now this solution:

Upload.upload({
    url: apiUrl,
    fields: params.fields,
    file: {"files[]": files}
})

And works well... except that server side i have $_FILES[0], $_FILES[1] etc.... instead of $_FILES["files"][0], $_FILES["files"][1] etc....

For me it's not a big problem... but with many file fields with different logic, it can cause problems.

@cwi-ezoutas Which version are you using? With the latest your solution give me the error above...

请试试 arrayKey: '' ,可是使得服务端接收的 files[0], files[1], files[2] 变成 files数组
请叫我红领巾。

Hi,

I am trying to use this module, but I am getting this error on Laravel Action:

$this->errors(['message' => 'Not an image.', 'code' => 400]);

This error happens in this if:

if ($validator->fails()) {
	return $this->errors(['message' => 'Not an image.', 'code' => 400]);
}

My image array:

$ngfBlobUrl : "blob:http://ci.dev/e1d8ae23-0ec5-4934-8285-47a956119fe2"
$ngfHeight : 843
$ngfWidth : 1097
lastModified : 1480357653411
lastModifiedDate : Mon Nov 28 2016 16:27:33 GMT-0200 (Horário brasileiro de verão)
name : "Q2.png"
size : 36338
type : "image/png"
webkitRelativePath : ""
proto : File

My Laravel is returning this error:

Allowed memory size of 134217728 bytes exhausted (tried to allocate 65461749 bytes)

I have already increased my memory_limit from 128M to 512M in php.ini but I am now getting other errors like :

Type error: Argument 1 passed to Illuminate\Routing\Middleware\ThrottleRequests::addHeaders() must be an instance of Symfony\Component\HttpFoundation\Response, null given, called in C:\wamp64\www\cadastroimoveis\vendor\laravel\framework\src\Illuminate\Routing\Middleware\ThrottleRequests.php on line 53

I have just copied the example codes with no changes... I am using laravel 5.3 and angular 1.5.

Thanks.