Reputation: 817
I'm having trouble preserving data extracted from a file read in by FileReader
.
In the scope of the onload
function the data seems to exist, but trying to store said data in a variable outside the scope does not seem to work.
MWE: http://jsfiddle.net/eqaw0hbf/1/
(Upload any text file and you'll see what I mean)
Upvotes: 1
Views: 645
Reputation: 1049
My inclination is to say the onload function is asynchronous. In other words it triggers and only executes the "function(e){}" scope when the loading has ended (hence the name "onloadend"). In the mean time the rest of your program outside the scope of the "function(e){}" will continue to execute while it waits for the loading to end. It's not that the data isn't being stored in the text variable. It's simply that the line 14 "alert(text)" call is happening before "function(e){}" scope has a chance to set the 'text' variable to something other than empty.
As is your code would start and execute lines 2-3 and then jump to line 10 (and print alert(text) which is just "" because the function(e) never executed and so text was never set to anything). When the server or request that is "lr.onloadend" finally receives its data then your program will jump back to line 6 and execute the scope within lr.onloadend = function(e){} and set the text variable.
What you should do is put any data processing that relies on text INSIDE the callback of onload, inside this scope: lr.onloadend = function(e){}
. Basically whenever you have an asynchronous function, anything that happens inside should be assumed to happen after all the code in any higher scope. Anything not inside a "callback" function will execute normally and in the order that you expect. Anything inside a callback function happens only when the callback gets triggered. So you can't make things outside a callback function rely on things that happen inside a callback function. There's no guarantee that information set inside an asynchronous callback that can 'trigger' whenever will be ready to use anywhere else.
This link does a decent job of explaining callbacks in Node.js/Javascript:
http://cwbuecheler.com/web/tutorials/2013/javascript-callbacks/
Upvotes: 3
Reputation: 7991
That's because it is running more or less asynchronously. The system is waiting for an event onloadend and then setting the text variable.
You can see this happening by putting in some sort of delay before your last alert.
function DoData(file) {
var lr = new FileReader();
var text = "";
lr.onloadend = function(e){
text = e.target.result;
};
lr.readAsText(file);
// this will display the correct result, after a delay of 1 second
setTimeout(function() {alert(text)}, 1000);
// this will display a blank string,
// because the text hasn't been loaded yet
alert(text);
}
Normally, what you will do is add the processing function for the text variable inside the onloadend event. That's the only time that you know, for a fact, that the text variable has been initialized correctly.
lr.onloadend = function(e){
text = e.target.result;
functionToProcessText(text);
};
Upvotes: 1