0

I'm wrting a function which takes an image from a file input from a form and enables me to put it in localstorage. The function I wrote to achieve this:

function getImage() {
    var pic = document.getElementById("image").files[0];
    var imgUrl;
    var reader = new FileReader();  
    reader.onload = function(e) {
      var imgURL = reader.result;
      saveDataToLocalStorage(imgURL);
      return imgUrl;
    }
}

Then in another function I call this function and create a JSON entry in which I store values from other form inputs including the image. It looks like this:

    var imgUrl = getImage();

    // Create new JSON entry
    var json_entry = {'title': titleField.val(),
                        'image': imgUrl,
                        'content': contentField.val(),
                        'location': location};

Sadly the value of imgUrl is undefined.. There are no console errors. What am I doing wrong? And how can I fix this?

  • 1
    Looks like you're trying to store binary data in localStorage, which doesn't support binary data ? – adeneo Dec 17 '13 at 17:11
  • Do you know how to fix it? –  Dec 17 '13 at 17:14
  • I don't know how to fix it. The code above is based on this example: http://jsfiddle.net/VXdkC/2/ –  Dec 17 '13 at 17:15
  • @adeneo Chrome, Opera and Safari allow anything to be saved in localStorage: http://stackoverflow.com/a/11173673/938089 (IE and FF have some limitations though). – Rob W Dec 17 '13 at 18:02

2 Answers2

1

I honestly don't know much about the FileReader object, but I can see just from glancing at your JS that (at least) one thing is off:

var imgUrl = getImage();

Your getImage function doesn't return anything; so imgUrl is definitely going to be undefined above.

If you want to do something with the result property of your FileReader, then you need to do so w/ a callback since you're handling the (asynchronous) onload event:

function getImage(callback) {
    // What are you doing with this?
    var pic = document.getElementById("image").files[0];

    var reader = new FileReader();  
    reader.onload = function(e) {
      var imgURL = reader.result;
      saveDataToLocalStorage(imgURL);

      // Note the difference here: rather than return from the event handler
      // (which effectively does nothing) we pass the result to a callback.
      callback(imgUrl);
    }

    // I assume you actually need to load something with the FileReader?
}

And then:

getImage(function(imgUrl) {
    var json_entry = {
        'title': titleField.val(),
        'image': imgUrl,
        'content': contentField.val(),
        'location': location
    };
});
Dan Tao
  • 125,917
  • 54
  • 300
  • 447
0

It looks like you are forgetting to set the reader to readAsDataUrl. Likely the value is coming back as undefined because localStorage does not inherently know how to serialize binary data. Setting the reader to readAsDataUrl changes reader.result onload.

var reader = new FileReader();  
reader.onload = function(e) {
  var imgURL = reader.result;
  saveDataToLocalStorage(imgURL);
  callback(imgUrl);
};
// add this line
reader.readAsDataURL(pic);

Have a look at this article, especially the section titled Reading Files. Note in the linked example the author uses e.target.result instead of reader.result. This should be the same value.

Josiah Ruddell
  • 29,697
  • 8
  • 65
  • 67