Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cloning a FileList object in JavaScript for file upload?

Alright, here is my situation. I have a JavaScript class that deals with AJAX form submissions and other related synchronous and asynchronous requests. It gathers data, then sets this data to a temporary storage for the request and then makes the request with the temporary storage data.

For example:

  • User starts building a request, puts NAME and LAST NAME to the form
  • This data is put into an object variable SUBMITDATA
  • When request is made then this data is cloned to another variable TEMPSUBMITDATA
  • Once the request is complete then the data that was used to make the request is still available (for debugging or other purposes)

This means that if two requests are ongoing at the same time through the same object, then I can still access the data that was used to make these requests.

Everything works as expected, until I want to use HTML5 FileList and FormData. While I can clone objects in JavaScript through relative ease, I cannot clone FileList. Here is an example:

<html>
<head>
    <script type="text/javascript">
        // This method is used to clone data objects
        function clone(object){
            if(object==null || typeof(object)!=='object'){
                return object;
            }
            // This line throws the error when FileList data is attempted to be cloned
            var tmp=object.constructor();
            for(var key in object){
                tmp[key]=clone(object[key]);
            }
            return tmp;
        }

        // This is an example data storage
        var submitData=new Object();
        submitData['some-data']='abc';

        function uploader(files){

            submitData['my-files']=files;

            // This clones the object and leads to the error because of FileList
            var tempSubmitData=clone(submitData);

            // HERE WOULD THE ACTUAL FORM SUBMIT HAPPEN
            // THIS EXAMPLE IS SHOWN FOR EASIER READING OF
            // THE PROBLEM EXPLAINED ABOVE

        }
    </script>
</head>
<body>
    <input type="file" name="myfile" value="" onchange="uploader(this.files);"/>
</body>

This leads me to my question, can I - at all - clone this type of data in any way so I could store it until the request is complete? Or is really the only way to make a new object every single time?

The new object solution is not good for me since my class works like a separate application, it has a log and other data that is useful for request tracking later on and it works really well in every case - until now that I stumbled upon HTML5 FileList and FormData use.

Any help would be appreciated!

like image 483
kingmaple Avatar asked Jan 21 '13 12:01

kingmaple


People also ask

What is cloning an object in JavaScript?

"Cloning" an object in JavaScript means creating a new object with the same properties as the original object. Objects in JavaScript are stored by reference, which means that two variables can point to the same object in memory. Modifying one object variable can impact other variables.

Is FileList an array?

A FileList is an array-like object that represents a collection of File objects returned by the files property of the HTML <input> element. You can use this to access the list of files selected with the <input type="file"> element.

What is FileList used for?

FileList is a command-line utility that generates a CSV file listing the contents of a given directory. By default, the list includes the file name, size, and path, as well as the last-access, last-modified, and creation dates, etc. You can easily import all results to a spreadsheet or database.


1 Answers

If you're using jQuery you can use the extend method to clone an object like this.

var clonedObject = $.extend(true,{},yourObject);

If you're not maybe you can use in this case the native Object.create()

var clonedObject = Object.create(yourObject);

The last is not a copy (but an empty object with the properties and functions of the former one as part of it's prototype, if i'm not mistaken), but it's similar and I think it would work for you in this case.

like image 106
Astaroth Avatar answered Sep 20 '22 15:09

Astaroth