Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTML 5 File Reader reading javaScript files

I'm trying to allow users to drag and drop a folder containing JavaScript files into an html5 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 I'm 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?

like image 253
Ivan Bacher Avatar asked Dec 19 '13 14:12

Ivan Bacher


People also ask

How do I read a JavaScript file?

To read a file, use FileReader , which enables you to read the content of a File object into memory. You can instruct FileReader to read a file as an array buffer, a data URL, or text. // Check if the file is an image.

What is the use of FileReader in JavaScript?

The FileReader object lets web applications asynchronously read the contents of files (or raw data buffers) stored on the user's computer, using File or Blob objects to specify the file or data to read.

Can HTML read local files?

Thankfully, with HTML5 we can now read files from the local file system. This means we can create apps that work better offline. The HTML input element of type="file" allows users to select one or more files from the local file system.

Can JavaScript read file system?

The main idea of the solution is: the JavaScript code cannot access the file by having its local URL. But it can use the file by having its DataURL: so if the user browses a file and opens it, JavaScript should get the "DataURL" directly from HTML instead of getting "URL".


2 Answers

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 ...
like image 62
user13500 Avatar answered Oct 07 '22 17:10

user13500


$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.readAsText($scope.files[i]);
    }
};
like image 26
nils Avatar answered Oct 07 '22 19:10

nils