0

I've a list which contains upload files:

let files = [File, File, File...];

and another upload file to compare:

let file = ...;

I want to check the file exists in the list or not (by comparing name/width/height/size/type);

Here is my way:

let f = files.find(function (x) {
    return x.name === file.name && x.type === file.type &&
           x.width === file.width && x.height === file.height &&  
           x.size === file.size;
});

if (f) {
    // exist
}

But x.width, x.height, file.width and file.height always return undefined.

undefined always equals to undefined (of course =))), but it's not my mean, I want to get the real value instead.

Thanks to this answer, I've edited some where but not finished yet.

let f = files.find(function (x) {
    let x_img = new Image();
    x_img.onload = function () {

        let file_img = new Image();
        file_img.onload = function () {

            // we can compare x_img width/height and file_img width/height here
            // but these functions look like the callback function
            // so we can't delay to get width and height

        };
        file_img.src = window.URL.createObjectURL(file);

    };
    x_img.src = window.URL.createObjectURL(x);

    // the main predicate here
    return x.name === file.name && x.size === file.size && x.type === file.size &&...

    // and how to compare width and height?
});

Can you help me to complete the code? Thank you!

Community
  • 1
  • 1
  • Depending on your requirements comparing `name`, `size` and `lastModified` should be enough to detect if the user selected the same file twice. – Prinzhorn May 12 '17 at 16:42
  • @Prinzhorn Thank you, that also means: I can't get and compare `width/height` in this case? –  May 12 '17 at 16:48

1 Answers1

0

get the naturalWidth and naturalHeight as below

var x = {
  name: "crayola-rango.jpg",
  type: "image/jpeg",
  width: 896,
  height: 259,
  size: 37596
}; //file to compare
function find(x, files, callback) {
  var len = files.length,
    i,
    _find = false,
    fun = function (file, callback) {
      var img = new Image();
      img.onload = function () {
        // no longer need to read the blob so it's revoked
        window.URL.revokeObjectURL(file);
        var width = img.naturalWidth,
          height = img.naturalHeight;
        if (x.name === file.name && x.type === file.type && x.width === width && x.height === height && x.size == file.size) {
          callback(file);
          _find = true;
        }
      }
      img.src = window.URL.createObjectURL(file);
    };
  for (var i = 0; i < len; i += 1) {
    if (_find) {
      break;
    }
    fun(files[i], callback);
  }
}
//only test
var file = document.getElementById("files");
file.addEventListener("change", function () {
  //call this
  find(x, file.files, function (file) {
    console.log(file);
  });
});
<input id="files" type="file" multiple>
alessandrio
  • 4,282
  • 2
  • 29
  • 40
  • Thank you but I can't put the main predicate into the `onload` function. This won't work: `img.onload = function () { return x.name === file.name && img.naturalWidth === file.naturalWidth... }` –  May 12 '17 at 16:47