Is there a way to generate zip from file dropped in dropzone and then send that zip file to server?
I'm generating zip from the file using JSZip in sending event of dropzone:
this.on("sending", function(file, xhr, formData) {
var zip = new JSZip();
zip.file("Hello.csv", file);
zip.generateAsync({ type: "blob" }).then(function(content) {
// see FileSaver.js
saveAs(content, "example.zip");
});
});
How do I make dropzone to send this file instead of the one user added?
This worked for me on dropzone 5.7.0, but I used the "addedFile" event instead:
this.on("addedfile", function (file) {
if (file.done) {
return;
}
const dz = this;
dz.removeFile(file);
let z = new JSZip();
z.file(file.name, file);
z.generateAsync({
type: "blob",
compression: "DEFLATE",
compressionOptions: { level: 9}
}).then(function(content) {
let f = new File([content], file.name);
f.done = true;
dz.addFile(f);
});
});
I added compression (the default for JSZip is STORE) and retained the file.name to make the zipping transparent to the user (however they will still see the smaller size).
p.s. I'm not loving the addition of the f.done field either...better solutions are welcome.
Related
How do I get input file path using NeutralinoJS?
My Code:
<input type="file" id="inputFile">
const inputFilePath = document.getElementById('inputFile').files[0].path
console.log(inputFilePath)
I don't think browsers allow you to get file paths.
You could use the file picker API instead os.showDialogOpen(DialogOpenOptions):
https://neutralino.js.org/docs/api/os#osshowdialogopendialogopenoptions
<button onclick="onFileUpload()">
async onFileUpload () {
let response = await Neutralino.os.showDialogOpen({
title: 'Select a file'
})
console.log(`You've selected: ${response.selectedEntry}`)
}
Why do you need the path? If you need the content from the upload file you can get it via javascript filereader API and use the contents.
If you need the file for later use you can read the file via js filereader and then create and save a new file with filesystem.writeFile(WriteFileOptions) to your prefered location (maybe app internal temp path). Be sure the destination path exists. For that you can use filesystem.createDirectory(CreateDirectoryOptions).
Example with jQuery:
jQuery(document).on('change','#myUpload',function(){ //Click on file input
if(jQuery(this).val().length > 0){ //Check if a file was chosen
let input_file = this.files[0];
let file_name = input_file.name;
let fr = new FileReader();
fr.onload = function(e) {
fileCont = e.target.result;
//Do something with file content
saveMyFile(file_name, fileCont); //execute async function to save file
};
fr.readAsText(input_file);
}
});
async function saveMyFile(myFileName, myFileContent){
await Neutralino.filesystem.createDirectory({ path: './myDestPath' }).then(data => { console.log("Path created."); },() => { console.log("Path already exists."); }); //create path if it does not exist
//write the file:
await Neutralino.filesystem.writeFile({
fileName: './myDestPath/' + myFileName,
data: myFileContent
});
}
You can use the Neutralino.os API for showing the Open/Save File Dialogs.
This is A Example For Opening A File.
HTML:
<button type="button" id="inputFile">Open File</button>
JavaScript:
document.getElementById("inputFile").addEventListener("click", openFile);
async function openFile() {
let entries = await Neutralino.os.showOpenDialog('Save your diagram', {
filters: [
{name: 'Images', extensions: ['jpg', 'png']},
{name: 'All files', extensions: ['*']}
]
});
console.log('You have selected:', entries);
}
I have written function where I want to download an xlsx file via a service. Download also works so far. But when I open the file I get the error message file extension or file format is invalid. How can I solve the problem?
Code:
// Service
getDownloadPlan(): Observable<any> {
const url = `/download-plan?sales-plan=0&personnel-plan=0&investment-plan=0&loan-plan=0&material-cost-plan=0`;
return this.http.get(`${environment.baseUrl}` + url, { responseType: 'blob'});
}
// TS
downloadPlanBwa() {
this.planBwaService.getDownloadPlan().subscribe(response => {
const downloadFile: any = new Blob([response], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
fileSaver.saveAs(downloadFile, 'Plan');
}, error => console.log('ERROR'),
() => console.log('SUCCESSFUL')
);
}
If i use the MIME-Type application/vnd.ms-excel;charset=utf-8 this is for the xls-format then it works.
What do I need to change in my code to successfully open xlsx files?
I did as in the documentation (https://developers.google.com/drive/api/v3/manage-uploads#http---single-request), but it doesn't work:
var fileMetadata = {
name: e.target.files[j].name,
parents: this.currentDirectoryId ? [this.currentDirectoryId] : []
}
var media = {
mimeType: e.target.files[j].type,
body: e.target.files[j]
}
window.gapi.client.drive.files.create({
resource: fileMetadata,
media: media,
fields: 'id, name, mimeType, createdTime'
}).then(res => console.log(res))
File is created, but empty and named "Untitled" with mimeType "application/octet-stream"
Issue and workaround:
When I tested gapi.client.drive.files.create, it seems that although this method can create new file with the metadata, the file content cannot be included. So in this answer, in order to upload a file by including the file metadata, I would like to propose to upload a file with multipart/form-data using fetch of Javascript. In this case, the access token is retrieved by gapi.auth.getToken().access_token.
Unfortunately, from your script, I couldn't understand about e.target. So in this sample script, I would like to propose the sample script for uploading a file, which is retrieved from the input tag, with the metadata.
Sample script:
HTML side:
<input type="file" id="files" name="file">
Javascript side:
const files = document.getElementById("files").files;
const file = files[0];
const fr = new FileReader();
fr.readAsArrayBuffer(file);
fr.onload = (f) => {
const fileMetadata = {
name: file.name,
parents: this.currentDirectoryId ? [this.currentDirectoryId] : [] // This is from your script.
}
const form = new FormData();
form.append('metadata', new Blob([JSON.stringify(fileMetadata)], {type: 'application/json'}));
form.append('file', new Blob([new Uint8Array(f.target.result)], {type: file.type}));
fetch('https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart', {
method: 'POST',
headers: new Headers({'Authorization': 'Bearer ' + gapi.auth.getToken().access_token}),
body: form
}).then(res => res.json()).then(res => console.log(res));
};
In this script, the file retrieved from input tag is uploaded to Google Drive with multipart/form-data.
Note:
In this script, it supposes that your authorization script can be used for uploading a file to Google Drive. Please be careful this.
In this answer, as a sample script, the file is uploaded with uploadType=multipart. In this case, the maximum file size is 5 MB. Please be careful this. When you want to upload the file with the large size, please check the resumable upload. Ref
References:
Using Fetch
Files: create
Upload file data
Perform a resumable upload
This URL below points to a zip file which contains a file called bundlesizes.json. I am trying to read the contents of that json file within my React application (no node server/backend involved)
https://dev.azure.com/uifabric/cd9e4e13-b8db-429a-9c21-499bf1c98639/_apis/build/builds/8838/artifacts?artifactName=drop&api-version=4.1&%24format=zip
I was able to get the contents of the zip file by doing the following
const url =
'https://dev.azure.com/uifabric/cd9e4e13-b8db-429a-9c21-499bf1c98639/_apis/build/builds/8838/artifacts?artifactName=drop&api-version=4.1&%24format=zip';
const response = await Axios({
url,
method: 'GET',
responseType: 'stream'
});
console.log(response.data);
This emits the zip file (non-ascii characters). However, I am looking to read the contents of the bundlesizes.json file within it.
For that I looked up jszip and tried the following,
var zip = new JSZip();
zip.createReader(
new zip.BlobReader(response.data),
function(reader: any) {
// get all entries from the zip
reader.getEntries(function(entries: any) {
if (entries.length) {
// get first entry content as text
entries[0].getData(
new zip.TextWriter(),
function(text: any) {
// text contains the entry data as a String
console.log(text);
// close the zip reader
reader.close(function() {
// onclose callback
});
},
function(current: any, total: any) {
// onprogress callback
console.log(current);
console.log(total);
}
);
}
});
},
function(error: any) {
// onerror callback
console.log(error);
}
);
However, this does not work for me, and errors out.
This is the error I receive
How can I read the contents of the file within the zip within my React application by using Javascript/Typescript?
I am trying to upload a sound file from ngCordova's $cordovaCapture service to UploadCare. The uploadcare.fileFrom('object') keeps failing with an'upload' error. I have the public key set. I am able to upload the file by sending it through and tag and accessing document.getElementById('fileTag').files[0].
$cordovaCapture.captureAudio()
.then(function (audioData) {
return uploadcare.fileFrom('object', audioData[0])
.done(function (fileInfo) {
console.log(fileInfo);
}).fail(function (err) {
console.log(err);
})
})
the audioData[0] object looks like this
MediaFile {
end:0
fullPath:"file:/storage/emulated/0/Sounds/Voice%20002.m4a"
lastModified:null
lastModifiedDate:1481324751000
localURL:"cdvfile://localhost/sdcard/Sounds/Voice%20002.m4a"
name:"Voice 002.m4a"
size:49227
start:0
type:"audio/mpeg"
} __proto__:File
I thought the problem might be that the object is a MediaFile rather than a File but I could use some help casting one to the other.
FileEntry
filesystem:FileSystem
fullPath:"/Sounds/Voice 002.m4a"
isDirectory:false
isFile:true
name:"Voice 002.m4a"
nativeURL:"file:///storage/emulated/0/Sounds/Voice%20002.m4a"
__proto__:Entry
File
end:49227
lastModified:1481324751000
lastModifiedDate:1481324751000
localURL:"cdvfile://localhost/sdcard/Sounds/Voice%20002.m4a"
name:"Voice 002.m4a"
size:49227
start:0
type:"audio/mpeg"
__proto__:Object
using window.resolveLocalFileSystemUrl() you end up with the above FileEntry object that give the above File object but uploadcare still fails with an "upload" error.
Using ngCordova $cordovaFileTransfer() you can send audio files to uploadcare.
var fileName = filePath.split('/').pop();
var uploadcareOptions = {
fileKey: "file",
fileName: fileName,
chunkedMode: false,
mimeType: 'audio/mp4',
params: {
"UPLOADCARE_PUB_KEY": "upload-care-public-key",
"UPLOADCARE_STORE": 'auto',
fileName: fileName
}
};
return $cordovaFileTransfer.upload('https://upload.uploadcare.com/base/', filePath, uploadcareOptions)
The important part is to specify the mime type when sending files as uploadcare will assume it's a image otherwise.
uploadcare.fileFrom uploads a file from a native file object. Try this:
window.resolveLocalFileSystemURL(audioData[0].localURL,function(fileEntry){
fileEntry.file(function(file) {
uploadcare.fileFrom('object', file);
...
});
});