user1977132
user1977132

Reputation: 497

Javascript File Handling

I am trying to load a client side text file using drag and drop. I've been looking at the example code and tutorials here: http://www.thebuzzmedia.com/html5-drag-and-drop-and-file-api-tutorial/ and here http://blog.teamtreehouse.com/reading-files-using-the-html5-filereader-api

Everything works correctly up until the reader.onload event.

function handleFiles(files) 
{
var file = files[0];
var reader = new FileReader();

//create function to deal with the file once it is loaded 
reader.onload = handleLoadedFile();

// begin the read operation
reader.readAsText(file);

}

function handleLoadedFile(event)
{
alert(event.target.result);
}

I thought the text should be in event.target.result but it's not! The alert doesn't fire.

Upvotes: 0

Views: 1055

Answers (1)

hgoebl
hgoebl

Reputation: 13007

Instead of

//create function to deal with the file once it is loaded 
reader.onload = handleLoadedFile();

you should write

//store reference to function to deal with the file once it is loaded 
reader.onload = handleLoadedFile;

Explanation:

When writing eventhandler = afunction() the eventhandler stores the result of the function, in your case this is undefined, since your handleLoadedFile does not return anything.

In case of eventhandler = afunction the function is not evaluated at the time of setting the handler. Only a reference to the function is stored. At the time the event fires, the stored reference will be evaluated with the () operator (probably this is not really the correct name, but you can at least think of () beeing an operator).

BTW this is a mistake which is made by experienced JavaScript programmers quite often. And there are cases where this is correct, e.g.:

reader.onload = createEventListener('success');
reader.onerror = createEventListener('error');

function createEventListener(type) {
    return function(event) {
        var content;
        if (type === 'success') {
            content = processMyFile(event.target.result);
        } else {
            content = 'An Error occurred. Please try another file.';
        }
        $('#content').html(content);
    }
}

So you can see it is not wrong in all cases not to use () when setting an event handler. I hope I didn't confuse you too much, since the construct above contains a powerful language feature of JavaScript (namely Closures) which takes some time to be well understood.

FYI: There are other ways to call a function when you have a reference to it: call and apply just to avoid down-votes from the JavaScript gurus ;-)

Additional hint: Please never use alert() for debugging your code. When testing with modern browsers (Internet Explorer < 11 should be avoided) you have a much better way to trace your code: console.log() and other methods of console. You'll love to use it because you don't have to click the OK button and you don't change the behaviour of your asynchronous operations as dramatically as with alert. Read Mastering Console Logging and play around with it - you'll never look back to alert!

Upvotes: 2

Related Questions