4

This is my code :

var fr = new FileReader();
var readFiles;
var fileI;
var files;

fr.onload = () => {
  readFiles.push(fr.result);
  fileI ++;
  if (fileI < files.length) {
    fr.readAsDataURL(files[fileI]);
  }
};

function getVideoImage(path, secs, callback) {
  var me = this, video = document.createElement('video');
  video.onloadedmetadata = function() {
    if ('function' === typeof secs) {
      secs = secs(this.duration);
    }
    this.currentTime = Math.min(Math.max(0, (secs < 0 ? this.duration : 0) + secs), this.duration);
  };
  video.onseeked = function(e) {
    var canvas = document.createElement('canvas');
    canvas.height = video.videoHeight;
    canvas.width = video.videoWidth;
    var ctx = canvas.getContext('2d');
    ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
    var img = new Image();
    img.src = canvas.toDataURL();
    callback.call(me, img, this.currentTime, e);
  };
  video.onerror = function(e) {
    callback.call(me, undefined, undefined, e);
  };
  video.src = path;
}

$uploadFiles.on("input", () => {
  files = $uploadFiles[0].files;
  var value = $uploadFiles[0].value;
  fileI = 0;
  readFiles = [];
  fr.readAsDataURL(files[0]);
  for (var i = 0; i < files.length; i++) {
    var format = files[i].name.split(".").pop().toUpperCase();
    var thumbnail;
    getVideoImage(readFiles[i], 0, (img) => {
      thumbnail = img;
    });
    if (fileFormat.video.includes(format)) {
      propertiesData.FILES.contents[0].push({
        thumbnail: thumbnail,
        title: files[i].name,
        file: readFiles[i]
      });
    } else if (fileFormat.image.includes(format)) {
      console.log(readFiles);
      console.log(i);
      console.log(readFiles[i])
      propertiesData.FILES.contents[1].push({
        thumbnail: readFiles[i],
        title: files[i].name,
        file: readFiles[i]
      });
    } else if (fileFormat.audio.includes(format)) {
      propertiesData.FILES.contents[2].push({
        thumbnail: "Assets/Logo.PNG",
        title: files[i].name,
        file: readFiles[i]
      });
    } else {
      alert("File Format Not Supported");
    }
    $("#properties-left-menu li[style='color: ${color[1]}']")
  }
});

It reads the uploaded files and saves the raw files in data object(propertiesData). The problem is this part :

      console.log(readFiles);
      console.log(i);
      console.log(readFiles[i])
      propertiesData.FILES.contents[1].push({
        thumbnail: readFiles[i],
        title: files[i].name,
        file: readFiles[i]
      });

console.log(readFiles); shows array of raw files like this and console.log(i); shows the proper index so console.log(readFiles[i]); is supposed to show one of the raw file string, but it's showing only undefined. Why?

  • What does `console.log(i)` output? `FileReader` `onload` event is asynchronous, `for` loop is synchronous unless `async/await` is used. – guest271314 Feb 02 '19 at 01:53
  • @guest271314 `console.log(i)` outputs proper index(0, 1, 2, 3...) – Sprout - Tuple Feb 02 '19 at 01:57
  • What is the purpose of `if (fileI < files.length) { fr.readAsDataURL(files[fileI]); }` within `FileReader` `onload` handler? Is the `multiple` attribute set? Why is `fr.readAsDataURL(files[0])` executed where the next line is a `for` loop which iterates `files` `FileList` object? – guest271314 Feb 02 '19 at 02:00

1 Answers1

1

For performance reasons, the browser console only evaluates references (like object references or arrays) at a later time. So, it does not show you the actual content at the time, that the log statement was executed.

From MDN:

Please be warned that if you log objects in the latest versions of Chrome and Firefox what you get logged on the console is a reference to the object, which is not necessarily the 'value' of the object at the moment in time you call console.log(), but it is the value of the object at the moment you click it open.

To get the actual content at that time, use

console.log(readFiles.toString());

You will then see, that at this time the array is still empty, because FileReader.readAsDataURL() is executed asynchronously.

Further reading:

NineBerry
  • 26,306
  • 3
  • 62
  • 93