1

I have the following javascript example: https://jsfiddle.net/rdqwnd9n/

It consists of a file upload element, and an image element, with the following javascript code:

var input = document.querySelector('input');
var readFiles = function(){
  var reader = new FileReader();
  reader.readAsDataURL(files[0]);
  console.log(reader.result);

  var img = document.querySelector('img');
  img.src = reader.result;
}

I read the uploaded file as a dataURL, then feed that (assumedly) picture back to an image element. What am I missing here?

Joshua M. Moore
  • 391
  • 4
  • 15
  • `readAsDataUrl` is an asynchronous operation. See https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsDataURL#Example for an example – Phil Sep 12 '17 at 01:37
  • 1
    you're missing... everything... it's `input.files[0]` not `files[0]`. and where is the callback for the reader if the image is read? – Joshua K Sep 12 '17 at 01:38
  • 1
    And you absolutely don't need a FileReader to display an image from an user's input, instead simply use the synchronous `img.src = URL.createObjectURL(file);` method. – Kaiido Sep 12 '17 at 01:39
  • fixed your broken [fiddle](https://jsfiddle.net/rdqwnd9n/1/) for you – Joshua K Sep 12 '17 at 01:41
  • Real fix : https://jsfiddle.net/rdqwnd9n/2/ – Kaiido Sep 12 '17 at 01:43
  • I think the synchronous way is ok, but if I want to preprocess the images or want to load a bunch of realy big pictures the asynchrouns way is ok, or do you disagree @Kaiido ? – Joshua K Sep 12 '17 at 01:46
  • @JoshuaK I strongly disagree, moreover with large files. `createObjectURL` only creates a symlink to the real file on disk, it doesn't even read it at this stage, it will only be read from disk when the image's will actually load it. On the other hand, FileReader will read the whole file, **copy** all its content in memory so that it can convert it's data to a dataURI, then you'll save this dataURI string in the document's markup and load it again in the image's loading process. [1/2] – Kaiido Sep 12 '17 at 02:17
  • @JoshuaK With the createObjectURL method, you charge the memory only once with the data, and it's easy for browsers to manage it, whereas with the FileReader, you charge it at least 3 times in memory. And this goes without saying that dataURIs are a nightmare to identify as http-cached, so it's possible that the browser will try to deflate the image, and call the parser every time you load it, while with the blobURI, it's quite easy to mark it as already parsed. [2/2] – Kaiido Sep 12 '17 at 02:18
  • @JoshuaK and for *preprocess* it depends on what you're talking about, but preprocessing a dataURI is always the wrong stand. If e.g you want to check that the file is indeed an image in a more secure way than relying on the file extension (Files MIME types are checked on it in browsers...), then yes a FileReader is ok, but you'd use the `readAsArrayBuffer` method, and only on a small portion of the File (e.g `file.slice(0,8)` should cover most magic numbers) [3/2 u_u] – Kaiido Sep 12 '17 at 02:22
  • @Kaiido agree in every single point. and yes: I meant preprocessing the `readAsArrayBuffer`-data in different ways, not the dataURI – Joshua K Sep 12 '17 at 11:04

0 Answers0