Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Waiting for FileReader to complete before continuing

So I am starting to work with HTML5 and JS for the first time to do some experiments for a future game. I am using FileReader to read in a local text file that will represent a map, and using a script to return an array of arrays based on the text read in.

The problem is, I am having trouble with undefined variables.. because my code is executing before FileReader is able to read in the input file and do its processing. This is my block that reads in:

document.getElementById('input').addEventListener('change', function() {
        var file = this.files[0];
        var reader = new FileReader();
        reader.onload = function(e) {
            let map = readMap(e.target.result);
        }
        reader.readAsText(file);
    }, false);

readMap() is an external function that simply takes the raw text and returns a 2d array based on it. This all works great.. and I tested that by logging inside of the readMap function. The issue is that I am referencing this 'map' variable later on in this file in order to read it, render it, etc. I immediately get 'Uncaught ReferenceError: map is not defined' when loading my code. This makes perfect sense... since the above block did not yet get to execute.. as it is still waiting on the user to select an input file.

Here is one of the few functions that need access to the 'map' later on in the code:

function drawMap() {
        let x = 0;
        let y = 0;
        for(var i=0; i<map.length;i++) {
            for(var j=0; j<map[i].length;j++) {
                if(map[i][j] === 1) {
                    ctx.fillRect(x,y,BLOCK_SIZE,BLOCK_SIZE);
                    x+=BLOCK_SIZE;
                }
                else if(map[i][j] === 'S') {
                    player.x = x;
                    player.y = y;
                    x+=BLOCK_SIZE;
                }
                else {
                    x+=BLOCK_SIZE;
                }
            }
            x=0;
            y+=BLOCK_SIZE;
        }
    }

Im not sure if that helps, but I just wanted to give an example of how I need to use this array.

Being fairly new to JS, I am really not yet finished wrapping my head around the idea of onLoads and callbacks... but my feeling is that they are the way to go about making this work. I assume I need to somehow tell the rest of my code not to execute until the 'map' object is finished being created.

I hope that was clear. Any help is appreciated!

like image 727
JParrilla Avatar asked Oct 23 '17 20:10

JParrilla


1 Answers

Call the function drawMap() or any other function only after you have received the data, thus within reader.onload callback, if you want to access this map later, make map variable global e.g.:

var map;
document.getElementById('input').addEventListener('change', function() {
 var file = this.files[0];
    var reader = new FileReader();
    reader.onload = function(e) {
        map = readMap(e.target.result);
        drawMap();
    }
    reader.readAsText(file);
}, false);

Or you can also pass map variable to drawMap function:

document.getElementById('input').addEventListener('change', function() {
  var file = this.files[0];
    var reader = new FileReader();
    reader.onload = function(e) {
        let map = readMap(e.target.result);
        drawMap(map);
    }
    reader.readAsText(file);
}, false);

function drawMap(map) {
    let x = 0;
    let y = 0;
    for(var i=0; i<map.length;i++) {
        for(var j=0; j<map[i].length;j++) {
            if(map[i][j] === 1) {
                ctx.fillRect(x,y,BLOCK_SIZE,BLOCK_SIZE);
                x+=BLOCK_SIZE;
            }else if(map[i][j] === 'S') {
                player.x = x;
                player.y = y;
                x+=BLOCK_SIZE;
            }                else {
                x+=BLOCK_SIZE;
            }
        }
        x=0;
        y+=BLOCK_SIZE;
    }
}
like image 109
Roman Habibi Avatar answered Oct 04 '22 16:10

Roman Habibi