[英]Data from objects created from FileReader in a web app then passed to Google Apps Script client-side return empty, undefined, null
My web app has a few file input elements where the user can upload any number of files of different types.我的 web 应用程序有几个文件输入元素,用户可以在其中上传任意数量的不同类型的文件。 I'm trying to store all data first in an array the same size of the number of input elements, where each item in the said array contains an array of data (filename, blob, mimetype) from each uploaded file.我试图首先将所有数据存储在一个数组中,该数组的大小与输入元素的数量相同,其中所述数组中的每个项目都包含来自每个上传文件的数据数组(文件名、blob、mimetype)。
The user can choose to upload or not, but if they don't, I still need to save some reference for that row with an empty upload by getting its data attribute (header).用户可以选择上传或不上传,但如果他们不上传,我仍然需要通过获取其数据属性(标题)为空上传的那一行保存一些参考。
The data appears in the browser console, but it returns undefined/empty/null when accessed from the client side of Google Apps Script.数据显示在浏览器控制台中,但从 Google Apps 脚本的客户端访问时返回未定义/空/空。 I'm not very familiar with the FileReader.我对 FileReader 不是很熟悉。
On the server side, I want to create a file in Google Drive from each blob and finally store the URL in Sheets.在服务器端,我想从每个 blob 在 Google Drive 中创建一个文件,最后将 URL 存储在表格中。
Thanks in advance!提前致谢!
function saveFormData(){
var fileInputs = document.querySelectorAll('tr.result-row td > input.upload');
var firstUploadIndex = fileInputs[0].parentElement.parentElement.getAttribute('data-index');
//Loop through all upload rows
var uploads = []; //will be array of arrays of multi-uploaded files; each item inside belongs to 1 column in db
Array.from(fileInputs).forEach(input => {
var files = input.files; //object file list
if(files.length < 1){ //if there's no file in the upload input
var header = input.getAttribute('data-uploadtype'); //save the header name as reference
var fileData = [header, '', '', ''];
uploads.push(fileData);
} else { //if there's a file/s in the upload input
var innerUploads = []; //array of data for each file
//Loop through all these files
for(var i = 0; i < files.length; i++){
var currentFile = files[i];
if(!currentFile) return; //if no current file, just in case
const fr = new FileReader();
fr.onload = (e) => {
var data = e.target.result.split(','); //split current file
var fileData = { binary: data[1], mimeType: data[0].match(/:(\w.+);/)[1], filename: currentFile.name };
innerUploads.push(fileData);
}
fr.readAsDataURL(currentFile);
} //CLOSES FOR LOOP
uploads.push(innerUploads);
} //CLOSES IF
}); //CLOSES FOR EACH LOOP
google.script.run.saveToDrive(uploads);
} //CLOSES FUNCTION
I believe your goal is as follows.我相信你的目标如下。
fileInputs
and create an array of uploads
including the values like [header, '', '', '']
and { binary: data[1], mimeType: data[0].match(/:(\w.+);/)[1], filename: currentFile.name }
.您想要从fileInputs
检索值并创建一个uploads
数组,包括[header, '', '', '']
和{ binary: data[1], mimeType: data[0].match(/:(\w.+);/)[1], filename: currentFile.name }
。When I saw your script, I thought that the reason for your current issue is due to that FileReader is run with the asynchronous process.当我看到你的脚本时,我认为你当前问题的原因是因为 FileReader 是在异步进程中运行的。 This has already been mentioned in my 1st comment.这已经在我的第一条评论中提到了。
When this is reflected in your script, how about the following modification?当这反映在您的脚本中时,以下修改如何?
Please modify your Javascript as follows.请修改您的Javascript如下。
function getFiles(file) {
return new Promise((resolve, reject) => {
const fr = new FileReader();
fr.onload = e => {
const data = e.target.result.split(",");
const obj = { binary: data[1], mimeType: data[0].match(/:(\w.+);/)[1], fileName: file.name };
resolve(obj);
}
if (file) {
fr.readAsDataURL(file);
} else {
reject("No file");
}
});
}
async function saveFormData() {
var fileInputs = document.querySelectorAll('tr.result-row td > input.upload');
// var firstUploadIndex = fileInputs[0].parentElement.parentElement.getAttribute('data-index'); // This is not used in your showing script.
var uploads = [];
var ar = Array.from(fileInputs);
for (var i = 0; i < ar.length; i++) {
var files = ar[i].files;
if (files.length == 0) {
var header = ar[i].getAttribute('data-uploadtype'); //save the header name as reference
var fileData = [header, '', '', ''];
uploads.push(fileData);
} else {
for (var j = 0; j < ar[i].files.length; j++) {
var res = await getFiles(ar[i].files[j]).catch(err => console.log(err));
uploads.push(res);
}
}
}
console.log(uploads); // You can confirm the value in the log.
google.script.run.saveToDrive(uploads);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.