I am trying to load a xlsx file by clicking a button without using input . The file "seedFile" is inside my project structure .The logic ran correct when I used a input but for internal files I am facing this issue and getting an err.
var excelToJson =function (file) {
return new Promise(function (resolve, reject) {
var xlData = {};
var reader = new FileReader();
reader.readAsBinaryString(seedFile);
reader.onload = function (e) {
var data = e.target.result;
var workbook = XLSX.read(data, {
type: 'binary'
});
workbook.SheetNames.forEach(function (sheetName) {
xlData[sheetName] =
XLSX.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);
})
};
reader.onprogress = function (data) {
if (data.lengthComputable) {
var progress = parseInt(((data.loaded / data.total) * 100), 10);
console.log(progress);
}
}
reader.onerror = function (ex) {
reject(ex);
};
reader.onloadend = function () {
resolve(xlData)
}
})
}
var handleFiles = function (files) {
var file = seedFile
return excelToJson(file)
}
$("#seedFile").click(async () => {
handleFiles(this.files).then(function success(data) {
console.log(data);
grid.setData(data.Sheet1).getInstance().loadData()
}, function error(err) {
alerts.error(err);
})
})
TypeError: Failed to execute 'readAsBinaryString' on 'FileReader': parameter 1 is not of type 'Blob'. Is there any easy way to make the file as a blob internally ?
Related
The problem is when i do no not see the form data in the console. I do not know what is wrong. here is the code:
So I got firstly the nodes and tried to create a function thta reads the file and a function that returns a src that would be stored in the readForm data function
//nodes
const mainContainer = document.getElementById("main");
const postTitleNode = document.getElementById("postTitle");
const postDateNode = document.getElementById("postDate");
const postFileNode = document.getElementById("postFile");
const postContentNode = document.getElementById("postContent");
//image file reader
function readImageFile(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.addEventListener("load", () => {
resolve(reader.result);
});
reader.addEventListener("error", () => {
reject(reader.error);
});
reader.readAsDataURL(file);
});
}
//reading the src of the image uploaded
function readFileSrc(elementNode) {
return new Promise((resolve, reject) => {
elementNode.addEventListener("change", async () => {
const file = elementNode.files[0];
if (file.type.startsWith("image/")) {
const dataUrl = await readImageFile(file);
postFileNode.value = dataUrl;
resolve(dataUrl);
} else {
console.error("Selected file is not an image.");
reject("Selected file is not an image.");
}
});
});
}
//clear form data
function clearInputValue() {
postTitleNode.value = "";
postDateNode.value = "";
postFileNode.value = "";
postContentNode.value = "";
}
//get form Data
async function readFormData() {
//values: store the values in an object
const postFile = await readFileSrc(postFileNode);
const formData = {
title: postTitleNode.value,
postDate: postDateNode.value,
postFile: postFile,
postContent: postContentNode.value,
};
console.log(formData);
return formData;
}
//onClick function
async function onClickEvent() {
//read data
await readFormData();
//clear data after clicking
clearInputValue();
}
//buttons
const createPostButton = document.getElementById("modalCreatePostButton");
createPostButton.addEventListener("click", onClickEvent);
what can I do to solve the problem or where is my mistake? why am i not getting any data in the console
I am using ckeditor in my net.core project. While saving the datatable, the image I added does not appear, it is registered to the database as
<figure class="image"><img></figure>
and src= does not appear as in lowermost the image. My adapter function is as follows
class MyUploadAdapter
{
constructor(loader) {
// The file loader instance to use during the upload.
this.loader = loader;
this.urls = '/tr/UnitType/DocUploadImage';
}
// Starts the upload process.
upload() {
return this.loader.file.then(file => new Promise((resolve, reject) => {
this._initRequest();
this._initListeners(resolve, reject, file);
this._sendRequest(file);
}));
}
// Aborts the upload process.
abort() {
if (this.xhr) {
this.xhr.abort();
}
}
_initRequest() {
const xhr = this.xhr = new XMLHttpRequest();
xhr.open('POST', this.urls, true);
xhr.responseType = 'json';
}
// Initializes XMLHttpRequest listeners.
_initListeners(resolve, reject, file) {
const xhr = this.xhr;
const loader = this.loader;
const genericErrorText = `Couldn't upload file: ${file.name}.`;
xhr.addEventListener('error', () => reject(genericErrorText));
xhr.addEventListener('abort', () => reject());
xhr.addEventListener('load', () => {
const response = xhr.response;
if (!response || response.error) {
return reject(response && response.error ? response.error.message : genericErrorText);
}
resolve({
default: response.urls
});
});
if (xhr.upload) {
xhr.upload.addEventListener('progress', evt => {
if (evt.lengthComputable) {
loader.uploadTotal = evt.total;
loader.uploaded = evt.loaded;
}
});
}
}
// Prepares the data and sends the request.
_sendRequest(file) {
// Prepare the form data.
const data = new FormData();
data.append('upload', file);
this.xhr.send(data);
}
}
function MyCustomUploadAdapterPlugin(editor) {
editor.plugins.get('FileRepository').createUploadAdapter = (loader) => {
return new MyUploadAdapter(loader);
};
}
I want to export this.urly to src. How is it given correctly? Is it possible in this way, if not how should I do it please help
DecoupledEditor
.create(document.querySelector('#p_Ack')
,{
extraPlugins: [MyCustomUploadAdapterPlugin],
elements:
{
img: function (element) {
const img = document.querySelector("img");
img.src = this.url;
}
}
}
)
enter image description here
enter image description here
I solved the problem..
For friends who have the same problem, #KIM-DONGWON answered the solution on https://github.com/ckeditor/ckeditor5/issues/5709.
the next function is getting file and setting it in state obj (arr: [readerEvent.target.result]).
works fine when uploading one file,
fine with 2 and 3.
when I am trying to upload more then 3 files - only 3 uploaded .
I can see that the full (5) list of files is coming into the func by using console.log.
input:
<Input
onChange={handleChange}
type="file"
// accept="image/png, image/jpeg"
multiple
/>
----------------------------------------
Component:
const list = Object.keys(e.target.files).map((elm) => e.target.files[elm]);
list.map((file, index) => {
loadFile(file, index, setImagesList);
});
---------------------------------------------------------------------------------------
Util:
export default function loadFile(file, index, setImagesList) {
// console.log("another file ", file);
let image = new Image();
var reader = new FileReader();
reader.onloadend = function (readerEvent) {
image.src = readerEvent.target.result;
image.onload = function () {
setImagesList((old) => [
...old,
{
key: `${Date.now()}-${file.name}-${index}`,
arr: [readerEvent.target.result],
imageOriginalWidth: image.width,
imageOriginalHeight: image.height,
},
]);
};
};
reader.onerror = function (event) {
console.error("File could not be read! Code " + event.target.error.code);
};
reader.readAsDataURL(file);
}
OK
found a solution so I will share it.
sending to the util function the entire list and handle it there.
in util func I will update a state that will be the optional loaded file .
only after a check I will set the "real" images list - that will happen out of the util - inside the component:
useEffect(()=>{
uploaded.map((obj, index) => {
if (isValid) {
setImagesList((old) => [...old, obj]);
}
},[uploaded])
-----------------------------------
util :
export default function loadFiles(files, setUploaded) {
const reader = new FileReader();
let arr = [];
function readFile(index) {
if (index >= files.length || index > 5) {
setUploaded(arr);
return;
}
const file = files[index];
reader.onload = function (e) {
let image = new Image();
image.src = e.target.result;
image.onload = function () {
arr.push({
key: `${Date.now()}-${file.name}-${index}`,
name: file.name,
arr: [e.target.result],
imageOriginalWidth: image?.width,
imageOriginalHeight: image?.height,
});
readFile(index + 1);
};
};
reader.readAsDataURL(file);
}
readFile(0);
}
good luck!
I am using react-dropzone to handle file upload on my website. When successfully loading a file, the dropzone triggers the following callback:
onDrop: function (acceptedFiles, rejectedFiles) {
myFile = acceptedFiles[0];
console.log('Accepted files: ', myFile);
}
I would like to base64 encode this file. When doing :
var base64data = Base64.encode(myFile)
console.log("base64 data: ", base64data) // => base64 data: W29iamVjdCBGaWxlXQ==W29iamVjdCBGaWxlXQ==
Regardless of file uploaded, it always prints out the same string.
Am I missing something ? I need to base64 encode this file (always images)
This JS Bin is a working example of converting a File to base64: http://jsbin.com/piqiqecuxo/1/edit?js,console,output . The main addition seems to be reading the file using a FileReader, where FileReader.readAsDataURL() returns a base64 encoded string
document.getElementById('button').addEventListener('click', function() {
var files = document.getElementById('file').files;
if (files.length > 0) {
getBase64(files[0]);
}
});
function getBase64(file) {
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function () {
console.log(reader.result);
};
reader.onerror = function (error) {
console.log('Error: ', error);
};
}
If you want it in a neat method that works with async / await, you can do it this way
const getBase64 = async (file: Blob): Promise<string | undefined> => {
var reader = new FileReader();
reader.readAsDataURL(file as Blob);
return new Promise((reslove, reject) => {
reader.onload = () => reslove(reader.result as any);
reader.onerror = (error) => reject(error);
})
}
I can upload a single image converted to a blob to firebase 3 successfully. However, when I try to upload multiple images to firebase 3 from my ionic 1 app, it fails.
The console logs that the data was successfully uploaded. I cannot see it in the firebase storage UI. I only see the first image I selected.
This is the code that gets the images:
$scope.getImages = function () {
var options = {
maximumImagesCount: 10,
width: 1000,
height: 1000,
quality: 100
};
$cordovaImagePicker.getPictures(options)
.then(function (results) {
for (var i = 0; i < results.length; i++) {
$scope.selectedImages.push(results[i]);
var fileName = results[i].replace(/^.*[\\\/]/, '');
// the image storage path is different on android
var path = '';
if ($ionicPlatform.is("android")) {
path = cordova.file.cacheDirectory;
}
else {
path = cordova.file.tempDirectory;
} // end of android image rectification
$cordovaFile.readAsArrayBuffer(path, fileName)
.then(function (realImage) {
var imageBlob = new Blob([realImage], { type: "image/jpeg" });
imgUpload(imageBlob, fileName)
})
}
}, function (error) {
// error getting photos
console.log(error.name);
})
Below is the code for firebase service
function imgUpload(_imgBlob, _filename) {
var uploadsMetadata = {
cacheControl: "max-age=" + (60 * 60 * 24 * 365) // One year of seconds
};
//create the storage reference and use it to access
var storeRef = firebase.storage().ref();
var uploadTask = storeRef.child('images/' + _filename).put(_imgBlob, uploadsMetadata);
return new Promise(function (resolve, reject) {
uploadTask.on('state_changed', function (snap) {
console.log('Progress: ', snap.bytesTransferred, '/', snap.totalBytes, ' bytes');
}, function (err) {
console.log('upload error', err);
reject(err);
}, function () {
var metadata = uploadTask.snapshot.metadata;
var key = metadata.md5Hash.replace(/\//g, ':');
var fileRecord = {
downloadURL: uploadTask.snapshot.downloadURL,
key: key,
metadata: {
fullPath: metadata.fullPath,
md5Hash: metadata.md5Hash,
name: metadata.name
}
};
// uploadsRef.child(key).set(fileRecord).then(resolve, reject);
});
}); // end of Promise
// return snapshot;
} // end of function imgUpload
[Edited 2/15/2017]
Padrian, without knowing what your specific error(s) were in the code above I can only assume that your issue(s) are the same as what was dealing with, namely that the metadata.md5Hash was failing since the metadata wasn't defined. My code and your code are nearly identical barring the UI framework differences.
My first refactoring to remove the error was to removed the listening on events and went with just having a callback on the .put() like so:
storageRef.child(uploadFile.name).put(uploadFile).then(cb(snap)).catch(errCB(err))
I further refactored my code and just as mysteriously as there was an issue, there was no longer an issue. Below is my full code for processing the upload file. I placed the code inside an async.queue so I could limit the file uploads to 4 files at a time.
const q = async.queue(function (file, callback) {
let reader = new window.FileReader()
reader.onload = function (e) {
const tags = ExifReader.load(e.target.result)
if (tags['Orientation'].description === 'left-bottom') {
file.rotation = 'rotate(-90deg)'
}
}
reader.readAsArrayBuffer(file.file.slice(0, 128 * 1024))
let uploadTask = storageRef.child(file.file.name).put(file.file, uploadsMetadata)
file.uploadSuccess = false
file.uploadError = false
file.active = 'active'
uploadTask.on('state_changed',
function (snap) {
file.progress = snap.bytesTransferred / snap.totalBytes * 100
},
function (err) {
file.uploadError = true
file.errorMessage = err
callback(err)
},
function () {
let metadata = uploadTask.snapshot.metadata
let key = metadata.md5Hash.replace(/\//g, ':')
let pendingInventoryRecord = {
downloadURL: uploadTask.snapshot.downloadURL,
key: key,
metadata: {
fullPath: metadata.fullPath,
md5Hash: metadata.md5Hash,
name: metadata.name
},
style: file.invStyle,
size: file.invSize,
count: file.invCount,
rotate: file.rotation || ''
}
uploadRef.child(key).set(pendingInventoryRecord)
.then(function () {
pendingInventoryCountRef.child('counter').transaction(function (currentVal) {
return (currentVal || 0) + 1
})
callback(null, file)
})
.catch(function (err) { console.log(err) })
})
}, 4)