简体   繁体   中英

JavaScript object to file object

I'm working on adding images to page, do something with collection of added images (preview etc) and finally I want them save. Everything is cool until the files object is used to show or save the photo.

var input = document.getElementById('files');
var files = input.files;

as it is an array of objects read only - it is impossible to manipulate it freely. For working with that array friendly I maped it like that:

var addedFiles = added(files); 
function added(from) {
    return $.map(from, function (i) {
         var x = { lastModified: i.lastModified, lastModifiedDate: i.lastModifiedDate, name: i.name, size: i.size, type: i.type, webkitRelativePath: i.webkitRelativePath }
         return x;
    });
}

... then do something with those files - and I want to preview, and then save - but for example during preview I get an error:

Uncaught TypeError: Failed to execute 'readAsDataURL' on 'FileReader': parameter 1 is not of type 'Blob'.

    function readImage(file) {
        var reader = new FileReader();
        reader.addEventListener("load", function () {
            var image = new Image();

            image.addEventListener("load", function () {
                preview.innerHTML += drawHtml(this, file);
                window.URL.revokeObjectURL(image.src); //blob version
            }); 
            image.src = reader.result; //file version
            image.src = window.URL.createObjectURL(file) //blob version
        });
        reader.readAsDataURL(file); // here fire the error
    }

When I pass for testing originally file obj to above code every thing is working.

Question: How to create custom obj (in my case array of obj) that can be parse to file obj

PS In project I'm using jquery and javascript

Rather than mapping the File objects to new, incompatible objects, you could instead wrap them with the additional things you need, but then use the underlying original files when reading them:

const fileSelections = Array.prototype.map.call(input.files, file => ({
  // This will let you get to the underlying file in the wrapper objects
  file,

  // If you want pass-throughs, you can do stuff like this:
  get lastModified() { return file.lastModified },

  // And you can add your own properties/methods as you please
});

function readImage(fileSelection) {
  // Unwrap the file
  const file = fileSelection.file;

  const reader = new FileReader();
  reader.addEventListener("load", function () {
    const image = new Image();

    image.addEventListener("load", function () {
      preview.innerHTML += drawHtml(this, file);
      window.URL.revokeObjectURL(image.src); //blob version
    }); 
    image.src = reader.result; //file version
    image.src = window.URL.createObjectURL(file) //blob version
  });
  reader.readAsDataURL(file);
}

correct answer is blob - it's something amazing for me.

//from is the array of obj - files
  function added(from) {
                    var out = [];
                    for (var i = 0; i < from.length; i++) {
                        (function (obj) {
                            var readerBase64 = new FileReader();
                            var obj = from[i];
                            readerBase64.addEventListener("load", function () {
                                var fileBase64 = readerBase64.result;
                                var row = { name: obj.name, size: obj.size, type: obj.type, base64: fileBase64 }
                                out.push(row);
                            });
                            readerBase64.readAsDataURL(obj); 
                        })(from[i]);
                    }
                    return out;
                }

'out' is a table of my own objects with base64, so I can create images for preview and 'do something functions' in the end I'm going to use base64 for create files.

here link for question related to my next step - creating img from blob (where I'm using additional lib b64toBlob)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM