Javascript file reader does not get stored in array - javascript

I am trying to upload multiple images. So I read that I can generate a temporary url and send them with ajax.
The idea is push the url created with filereader into an array and the send with ajax but the url's are not pushed properly. When I see the result I got like an empty array:
But if I click the arrow I can see the url's inside
But them seems Inaccessible.
This is my code:
$('form').on('submit',function(e) {
e.preventDefault();
var filesToUpload = document.getElementById("myFile");
var files = filesToUpload.files;
var fd = new FormData();
var arr = [];
if (FileReader && files && files.length) {
for (i=0; i< files.length; i++){
(function(file) {
var name = file.name;
var fr = new FileReader();
fr.onload = function () {
arr.push(fr.result);
}
fr.readAsDataURL(file);
})(files[i]);
}
console.log(arr);
}
});
The final idea is convert to string JSON.stringify(arr) and then parse in php json_decode($_POST['arr']).
Of course this is not working because JSON.stringify(arr) gets empty.

Maybe the following simple solution works for you? I placed your console.log() and your ajax call into the fr.onload() method but fire it only, after your results array has been filled up with all values:
$('form').on('submit',function(e) {
e.preventDefault();
var filesToUpload = document.getElementById("myFile");
var files = filesToUpload.files;
var fd = new FormData();
var arr = [];
if (FileReader && files && files.length) {
for (var i=0; i< files.length; i++){
(function(file) {
var name = file.name;
var fr = new FileReader();
fr.onload = function () {
arr.push(fr.result);
if(arr.length==files.length) {
console.log(arr);
// place your ajax call here!
}
}
fr.readAsDataURL(file);
})(files[i]);
}
}
});

Related

javascript how can i run 2 file reader methods(readAsArrayBuffer() & readAsDataURL())?

i currently have the ff code my goal is to remove the extra filreader loop? is it possible to maybe chain the readAsArrayBuffer and readAsDataURL or load them both?
var images = [];
var files = dt.files.length;
for (i = 0; i < files; i++) {
var reader = new FileReader();
reader.fileId = i;
reader.onload = function (){
images[this.fileId].is_valid = true / false; // checks mime type
}
reader.readAsArrayBuffer(dt.files[i]);
for (i = 0; i < files; i++) {
var reader = new FileReader();
reader.fileId = i;
reader.onload = function (){
//load image
if(image[i].is_valid){
// do this
}else {
// do this
}
}
reader.readAsDataURL(dt.files[i]);

How to perform sha256 hash using sjcl.hash.sha256.hash on a file content?

I am trying to perform SHA256 hash on a file content using javascript.
I get the file using the following function
var fileReader = new FileReader();
var fileByteArray = [];
fileReader.onload = function(evt) {
if (evt.target.readyState == FileReader.DONE) {
var arrayBuffer = evt.target.result,
array = new Uint8Array(arrayBuffer);
fileHash = generateHashOfFileContent(array);
console.log('fileHash1: ' + fileHash);
}
}
fileReader.readAsArrayBuffer(this.files[0]);
And the hash function is
function generateHashOfFileContent(fileData){
var bitArray = sjcl.hash.sha256.hash(fileData);
var digest_sha256 = sjcl.codec.hex.fromBits(bitArray);
console.log("Sha256 "+digest_sha256);
return digest_sha256;
}
But it produce wrong hash data when I select a binary file
I can only produce actual hash using a text file and change the fileReader.readAsArrayBuffer(this.files[0]); -------> fileReader.readAsText(this.files[0]);
Can someone help me to figure out the problem
You should convert your TypedArray to bitArray:
var fileReader = new FileReader();
var fileByteArray = [];
fileReader.onload = function(evt) {
if (evt.target.readyState == FileReader.DONE) {
var arrayBuffer = evt.target.result,
array = new Uint8Array(arrayBuffer);
let bitArray = sjcl.codec.bytes.toBits(array)
fileHash = generateHashOfFileContent(bitArray);
console.log('fileHash1: ' + fileHash);
}
}
fileReader.readAsArrayBuffer(this.files[0]);
See https://github.com/bitwiseshiftleft/sjcl/wiki/Codecs

issue converting file to base 64bit javascript

I am trying to make a java script web resource for dynamics CRM that essentially lets a user chose a file to upload and then stores it onto the annotation entity. I know the general procedure to do this however it keeps uploading empty files. The data is not getting converted to base 64 using the base 64 function. I am having a hard time using the File reader function to convert the file uploaded into base 64. The dataURL variable keeps returning empty. Can someone help me convert the chosen file to base 64? this does not have to be dynamics specific I think its a general java script html problem. I think i am using the File reader function wrong.
Thank you
function uploadFile(event) {
var input = event.target;
var file = input.files[0];
//var file = document.getElementById("myFile").files[0];
var str;
var reader = new FileReader();
reader.onload = function() {
var dataURL = reader.result;
str = _arrayBufferToBase64(dataURL);
};
reader.readAsDataURL(input.files[0]);
var id = window.parent.Xrm.Page.data.entity.getId();
var nam = window.parent.Xrm.Page.data.entity.getEntityName();
var entity = {};
entity.Subject = "first new annotation3";
entity.NoteText = "way to go you just made a new annotation";
entity.DocumentBody = str;
entity.FileName = file.name;
entity.MimeType = file.type;
entity.ObjectId = {
Id: id,
LogicalName: nam
};
SDK.REST.createRecord(entity, "Annotation", SucessCallback2, errorCallback2);
}
function _arrayBufferToBase64(buffer) { // Convert Array Buffer to Base 64 string
var binary = '';
var bytes = new Uint8Array(buffer);
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode(bytes[i]);
}
return window.btoa(binary);
}
<
input type = "file"
id = "myFile"
placeholder = "Choose File"
onchange = "uploadFile(event)" >
i figured it out, for anyone else having a similar issue. It turns out that you cant take the data outside the onload function, you have to pass the data out to another function using a callback function. See below.
function uploadFile(event)
{
var input = event.target;
var file = input.files[0];
//var file = document.getElementById("myFile").files[0];
var str;
var reader = new FileReader();
reader.onload = function(eve){
var theResult = reader.result;
str = _arrayBufferToBase64(theResult);
AttachFileFunction(file.name,file.type,str);
};
reader.readAsArrayBuffer(file);

Base64-encoding a Videofile in js

So i've got a video file and the path to it (e.g. /outerfolder/innerfolder/video.mp4). I now want to encode this video with Base64 in JS so that I am able to store it in a database. If you could help me with the encoding of the video file, I would be very thankful.
Thanks in advance.
You could encode the file with the following function to convert your file to an ArrayBuffer:
[update]
//<input type=file id="encondeMP4">
var encodeMP4 = document.getElementById('encondeMP4');
You now add an event listener to when file input changes
window.onload = function () {
//add eventlisteners
encodeMP4.addEventListener('change', someFunction);
}
you need a function to handle the call from the eventlistener
function someFunction(){
encode(arrayBufferToString)
}
function encode(callback){
var file = encodeMP4.files[0];
var reader = new FileReader();
reader.onload = function(e){
var contents = e.target.result;
var contentBuffer = arrayBufferToString(contents);
var array = callback(contentBuffer);
}
reader.readAsArrayBuffer(file);
}
in var array you now have the MP4 enconded in binary, in the previous function is an internal variable so you'll need to adapt this code to your needs. Maybe a global container called YourEncodedMP4 = array
function arrayBufferToString(buffer) {
var binary = '';
var bytes = new Uint8Array( buffer );
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode( bytes[ i ] );
}
return binary;
}
you now are ready to call this function to convert the MP4 enconded String to a Base64 one.
Is up to you where the contents of var array would be stored, but remembered this call is asynchronous.
Now you could use this function using the container "YourEncodedMP4"
function stringToArrayBuffer(YourEncodedMP4) {
var arrBuff = new ArrayBuffer(YourEncodedMP4.length);
var writer = new Uint8Array(arrBuff);
for(var i = 0, len = YourEncodedMP4.length; i < len; i++){
writer[i] = YourEncodedMP4.charCodeAt(i);
}
return writer;
}
you now have a function that returns a Byte Array, than you could use
var base64String = btoa(String.fromCharCode.apply(null, new Uint8Array(stringToArrayBuffer(YourEncodedMP4))));
you'll end up with a StringBase64

How to read files from folder

Found this article which showing how to distinguish file upload from directory How to handle dropped folders but they not explain how I can handle the directory upload. Having difficulties to find any example. Anyone know how to get File instance of each file in directory?
Copied from that article:
<div id=”dropzone”></div>
var dropzone = document.getElementById('dropzone');
dropzone.ondrop = function(e) {
var length = e.dataTransfer.items.length;
for (var i = 0; i < length; i++) {
var entry = e.dataTransfer.items[i].webkitGetAsEntry();
if (entry.isFile) {
... // do whatever you want
} else if (entry.isDirectory) {
... // do whatever you want
}
}
};
Use DirectoryReader directoryEntry.createReader() , readEntries() for folders or , FileEntry file() for single or multiple file drops.
html
<div id="dropzone"
ondragenter="event.stopPropagation(); event.preventDefault();"
ondragover="event.stopPropagation(); event.preventDefault();"
ondrop="event.stopPropagation(); event.preventDefault(); handleDrop(event);">
Drop files
</div>
javascript
function handleFiles(file) {
console.log(file);
// do stuff with `File` having `type` including `image`
if (/image/.test(file.type)) {
var img = new Image;
img.onload = function() {
var figure = document.createElement("figure");
var figcaption = document.createElement("figcaption");
figcaption.innerHTML = file.name;
figure.appendChild(figcaption);
figure.appendChild(this);
document.body.appendChild(figure);
URL.revokeObjectURL(url);
}
var url = URL.createObjectURL(file);
img.src = url;
} else {
console.log(file.type)
}
}
function handleDrop(event) {
var dt = event.dataTransfer;
var files = dt.files;
var length = event.dataTransfer.items.length;
for (var i = 0; i < length; i++) {
var entry = dt.items[i].webkitGetAsEntry();
if (entry.isFile) {
// do whatever you want
console.log("isFile", entry.isFile);
entry.file(handleFiles);
} else if (entry.isDirectory) {
// do whatever you want
console.log("isDirectory", entry.isDirectory);
var reader = entry.createReader();
reader.readEntries(function(entries) {
entries.forEach(function(dir, key) {
dir.file(handleFiles);
})
})
}
}
}
plnkr http://plnkr.co/edit/eGAnbA?p=preview
After you drag some file from your disk. This event.dataTransfer.file is your fileList object.
Your could create a formData then
Add files from fileList to formData one by one.
In the end you could submit formData to server with Ajax

Categories