BuildingJarl BuildingJarl - 5 months ago 30
Javascript Question

HTML 5 File Reader reading javaScript files

Im trying to allow users to drag and drop a folder containing javascript files into an html 5 page. This is what i currently have:

$scope.files = [];

//Establish dropzone
var dropbox;
dropbox = document.getElementById("fileDragAndDrop");
dropbox.addEventListener("dragenter", dragenter, false);
dropbox.addEventListener("dragover", dragover, false);
dropbox.addEventListener("drop", drop, false);

//Events
function dragenter(e) {
e.stopPropagation();
e.preventDefault();
};
function dragover(e) {
e.stopPropagation();
e.preventDefault();
};
function drop(e) {
e.stopPropagation();
e.preventDefault();

var items = e.dataTransfer.items;

for (var i = 0, item; item = items[i]; i ++) {
var entry = item.webkitGetAsEntry();

if(entry) {
traverseFileTree(entry);
}
}
};

//resursive file walker
function traverseFileTree(item) {
if(item.isFile) {
$scope.$apply(function () {
$scope.files.push(item);
});
} else if (item.isDirectory) {
var dirReader = item.createReader();
dirReader.readEntries(function(entries) {
for (var i = 0; i < entries.length; i++) {
traverseFileTree(entries[i]);
}
});
}
};


So the dragging and dropping works, but im having problems reading the file content.

$scope.parse = function () {

for(var i = 0; i < $scope.files.length; i++) {

var fileReader = new FileReader();

fileReader.onload = function (e) {

console.log(fileReader.result);
};

fileReader.onerror = function(err) {
console.log(err);
};

fileReader.readAsBinaryString($scope.files[i]);
}
};


I am not getting any error messages, which makes it hard to debug. Am i doing something wrong? has anyone had any issues doing similar tasks?

Answer

Not sure what your $scope is but giving it a go.

As you use webkitGetAsEntry() I assume this is for Chrome. From the looks of it your code should give you an error. If it does not, there is likely something you have omitted. You should typically get something like:

Uncaught TypeError: Failed to execute 'readAsBinaryString' on 'FileReader': The argument is not a Blob.

in your $scope.parse function.


There is a few issues. One is that you probably would read files as text and not as binary string. Secondly readAsBinaryString() is deprecated, use readAsArrayBuffer() if you want to read binary data.

Further, the webkitGetAsEntry() returns a FileEntry, hence why you should get the error mentioned above. To read the file you could typically do:

$scope.files[i].file(success_call_back, [error_call_back]);

For example:

function my_parser(file) {
        var fileReader = new FileReader();

        fileReader.onload = function (e) {
            console.log(fileReader.result);
        };

        fileReader.onerror = function(err) {
            console.log(err);
        };
        console.log('Read', file);
        // Here you could (should) switch to another read operation
        // such as text or binary array
        fileReader.readAsBinaryString(file);
}

$scope.files[0].file(my_parser);

This will give you a File object as argument to my_parser(). Then you could typically check .type and use appropriate read function. (Though be aware of the slackness in MIME type. As in: do not rely on it, but use it as a hint.)

if (file.type.match(/application\/javascript|text\/.*/)) {
    // Use text read
} else if (file.type.match(/^image\/.*/)) {
    // Use binary read, read as dataURL etc.
} else ...
Comments