I am trying to post files (Video and Thumbnail) and object to server, but I have an issue because of the structure backend expects. When I do it from postman, this is how it looks like and it works:
{'name': ['Blabla'], 'user': ['8c3a636c-9d08-453d-9e59-7a0ec93200c4'], 'file': [<InMemoryUploadedFile: SampleVideo_1280x720_1mb.mp4 (video/mp4)>]}>
I am having trouble with passing the file like this, don't know how to do it. I tried to do it like this:
videoFile: File[] = [];
thumbnailFile: File[] = [];
files: File[] = [];
readVideoUrl(event:any) {
this.videoFile = [];
const eventObj: MSInputMethodContext = <MSInputMethodContext> event;
const target: HTMLInputElement = <HTMLInputElement> eventObj.target;
const files: FileList = target.files;
if (files) {
this.videoFile.push(files[0]);
this.videoModel.name = files[0].name;
}
if (event.target.files && event.target.files[0]) {
var reader = new FileReader();
reader.onload = (event: ProgressEvent) => {
this.videoUrl = (<FileReader>event.target).result;
}
reader.readAsDataURL(event.target.files[0]);
}
}
readThumbUrl(event:any) {
this.thumbnailFile = [];
const eventObj: MSInputMethodContext = <MSInputMethodContext> event;
const target: HTMLInputElement = <HTMLInputElement> eventObj.target;
const files: FileList = target.files;
if (files) {
this.thumbnailFile.push(files[0]);
}
if (event.target.files && event.target.files[0]) {
var reader = new FileReader();
reader.onload = (event: ProgressEvent) => {
this.thumbUrl = (<FileReader>event.target).result;
}
reader.readAsDataURL(event.target.files[0]);
}
}
I pass the model and files:
this.campaignService.createVideo(this.videoModel, this.files)
.subscribe(
(response: any) => {
},
(error) => {
console.log(error);
}
);
And here is the issue, how can I create the structure from above with form data, I used to do it like this:
postMultipart(url: string, data: any, files: File[]) {
const formData: FormData = new FormData();
// I understand this stringify is part of the issue,
// just put the code as it is at the moment.
formData.append('data', JSON.stringify(data));
for (const file of files) {
formData.append(file.name, file);
}
const result = this.http.post(url, formData)
.pipe(map((response: Response) => {
return response;
// }
}),
catchError(response => this.handleError(response))
);
return result;
}
But this passes everything like string, and backend is not expecting that. How can I get this (this is just video, the thumbnail is an image):
{'file': [<InMemoryUploadedFile: SampleVideo_1280x720_1mb.mp4 (video/mp4)>]}>
Related
I am trying to upload multiple images to firebase using angular fire.
And using a simple input file. how can I loop for this command to upload multiple images?
I am not using drag and drop, I need to use the input file, and I am using formControl to capture the url.
showPreview(event: any) {
if (event.target.files) {
for (let i = 0; i < event.target.files.length; i++){
const reader = new FileReader();
reader.onload = (event: any) => {
console.log(event.target.result);
this.selectedImage.push(event.target.result);
this.formCadastroAnuncio.patchValue({
fileSource: this.selectedImage
});
}
reader.readAsDataURL(event.target.files[i]);
}
}
else {
this.imgSrc = 'assets/img/image_placeholder.jpg';
}
}
onSubmit(formValue: any) {
this.isSubmitted = true;
const filelist = formValue.target.files;
for (const file of filelist) {
if (this.formCadastroAnuncio.valid) {
let filePath = `${formValue.telefone}/${this.selectedImage}_${new Date().getTime()}`
const fileRef = this.storage.ref(filePath);
this.storage.upload(filePath, this.selectedImage)
.snapshotChanges().pipe(
finalize(() => {
fileRef.getDownloadURL().subscribe((url) => {
formValue['fotos'] = url;
this.service.insertImageDetails(formValue);
})
})
)
.subscribe();
}
}
}
imageDetailsList!: AngularFireList<any>;
constructor(private firebase: AngularFireDatabase) { }
getImageDetailsList(){
this.imageDetailsList = this.firebase.list('imageDetails');
}
insertImageDetails(imageDetails:any) {
this.imageDetailsList.push(imageDetails);
}
I am using the xlsx to parse .xls files.
I am having an issue with the date format being different after parsing the file and would like to know why, and perhaps how to fix it?
Here is an example file that I have been working with, it is only 3 lines long.
here the code I have so far
import React, { Component } from 'react';
import { render } from 'react-dom';
import XLSX from "xlsx";
import './style.css';
class App extends Component {
constructor() {
super();
this.state = {
name: 'React'
};
}
xslToJson = workbook => {
var data = [];
var sheet_name_list = workbook.SheetNames;
return XLSX.utils.sheet_to_json(workbook.Sheets[sheet_name_list[0]], {raw: false});
};
handleFile = (file /*:File*/) => {
/* Boilerplate to set up FileReader */
const reader = new FileReader();
const rABS = !!reader.readAsBinaryString;
reader.onload = e => {
/* Parse data */
const bstr = e.target.result;
const wb = XLSX.read(bstr, { type: rABS ? "binary" : "array" });
/* Get first worksheet */
let arr = this.xslToJson(wb);
console.log(arr)
};
if (rABS) reader.readAsBinaryString(file);
else reader.readAsArrayBuffer(file);
};
handleChange = (e) => {
const files = e.target.files;
if (files && files[0]) {
this.handleFile(files[0]);
}
};
render() {
return (
<div>
<input
type="file"
onChange={this.handleChange}
className="inputfile"
id="embedpollfileinput"
/>
</div>
);
}
}
render(<App />, document.getElementById('root'));
in my xsl file, DD/MM/YYYY format is present.but when i parse xls file it shows me in MM/DD/YY
xslToJson = workbook => {
var data = [];
var sheet_name_list = workbook.SheetNames;
return XLSX.utils.sheet_to_json(workbook.Sheets[sheet_name_list[0]], {raw: false});
};
handleFile = (file /*:File*/) => {
/* Boilerplate to set up FileReader */
const reader = new FileReader();
const rABS = !!reader.readAsBinaryString;
reader.onload = e => {
/* Parse data */
const bstr = e.target.result;
const wb = XLSX.read(bstr, { type: rABS ? "binary" : "array" });
/* Get first worksheet */
let arr = this.xslToJson(wb);
console.log(arr)
};
if (rABS) reader.readAsBinaryString(file);
else reader.readAsArrayBuffer(file);
};
Initially, I have made loading here so like this
export function сonvertFilesToByteArray(e) {
const MAX_FILE_SIZE = 1024 * 1024 * 50; // 50MB
const files = Object.keys(e.target.files);
const asyncReadFile = eachFile =>
new Promise((resolve, reject) => {
if (e.target.files[eachFile].size > MAX_FILE_SIZE) {
return reject([{ message: `File ${e.target.files[eachFile].name} too large` }]);
}
const reader = new FileReader();
const targetFileInfo = {
contentType: e.target.files[eachFile].type,
filename: e.target.files[eachFile].name,
};
reader.readAsArrayBuffer(e.target.files[eachFile]);
reader.onload = () => {
resolve({ ...targetFileInfo, body: Array.from(new Uint8Array(reader.result)) });
};
reader.onerror = error => reject(error);
});
return Promise.all(files.map(asyncReadFile));
}
Here in the constant files, I define how many at my files and I apply a function to each of them.
And then I get my file(s) in the component
handleFileUpload = (e) => {
сonvertFilesToByteArray(e)
.then((result) => {
runInAction(() => {
this.files = [
...this.files,
...result,
];
});
})
.catch(err => runInAction(() => {
this.errors = [...this.errors, err[0].message];
}));
}
And put in this.files and finally my this.files looks like [{contentType: 'plain/text', filename: 'blabla', body: [123, 456, 23, ...] }]
Where [123, 456, 23...] there is my ArrayBuffer
But at such approach in spite of the fact that I use Promise.all, when loading files/files which have weight more ~ 2MB, the page is frozen, it is impossible to interact with her in any way (but I can scroll). Except as realization when each file are divided into chunks nothing has come to mind to correct a situation.
Ok, I try to rewrite the code: With chunks
export function сonvertFilesToByteArray(e) {
const MAX_FILE_SIZE = 1024 * 1024 * 50; // 50MB
const files = Object.keys(e.target.files);
const asyncReadFile = eachFile =>
new Promise((resolve, reject) => {
if (e.target.files[eachFile].size > MAX_FILE_SIZE) {
return reject([{ message: `File ${e.target.files[eachFile].name} too large` }]);
}
const file = e.target.files[eachFile];
let offset = 0;
console.log(offset, 'offset', file.size, 'size');
const defaultChunkSize = 64 * 1024; // bytes
const fileReader = new FileReader();
const blob = file.slice(offset, offset + defaultChunkSize);
const isEndOfFile = () => offset >= file.size;
const testEndOfFile = () => {
if (isEndOfFile()) {
console.log('Done reading file');
}
};
fileReader.readAsArrayBuffer(blob);
fileReader.onloadend = (event) => {
const target = (event.target);
if (target.error == null) {
const result = target.result;
offset += result.length;
testEndOfFile();
console.log(result, 'result');
resolve(result);
} else {
reject(target.error);
}
};
});
return Promise.all(files.map(asyncReadFile));
}
Here I receive the file and I divide it. But the problem is that if the file is more than a chunk, then I should bring together him from them again and again. But how to make it in my case? I can't understand it in any way...
Please help me :) What it is necessary to make to read the file in chunks and to receive it as ArrayBuffer?
I am trying to load a JSON file from local disk and use the data from it to fill a FabricJS canvas. I have problems on getting the data from the file.
This is what i have till now.
app.html
<input type="file" accept=".json" id="fileInput" (change)="loadFile($event)"/>
app.ts
loadFile(event) {
const eventObj: MSInputMethodContext = <MSInputMethodContext> event;
const target: HTMLInputElement = <HTMLInputElement> eventObj.target;
const files: FileList = target.files;
this.file = files[0];
const reader = new FileReader();
reader.readAsText(this.file, 'utf8');
this.canvas.loadFromJSON(this.file, this.canvas.renderAll.bind(this.canvas), function (o, object) {
console.log(o, object);
});
Any thoughts on how I can make this work?
FileReader has an async api.
You must register a callback to the onload event to get the data.
loadFile(event) {
const eventObj: MSInputMethodContext = <MSInputMethodContext> event;
const target: HTMLInputElement = <HTMLInputElement> eventObj.target;
const files: FileList = target.files;
this.file = files[0];
const reader = new FileReader();
reader.readAsText(this.file, 'utf8');
reader.onload = function() {
this.canvas.loadFromJSON(reader.result, this.canvas.renderAll.bind(this.canvas), function (o, object) {
console.log(o, object);
});
}
I have array of files and I need to format the file to json (object at this point) with bunch of other info. Here's what I have tried
const uploadData = Files.map((file) => {
const fr = new FileReader();
fr.readAsArrayBuffer(file);
fr.onload = (event) =>{
const fileData = event.target.result;
return {
query:{
documentName: file.name,
personId: personId,
serviceId: serviceID,
documentFile: fileData,
}
}
}
})
I want to use immutable techniques. I do have a guess why this doesn't work but have no idea how to fix it. I Think .map does not wait for filereader to read and thus returns only array of undefined values. I tried to use IIFE but was unsuccessfull.
const uploadData = [],
Files.forEach((file) => {
const fr = new FileReader();
fr.readAsArrayBuffer(file);
fr.onload = (event) =>{
const fileData = event.target.result;
uploadData.push(query:{
documentName: file.name,
personId: personId,
serviceId: serviceID,
documentFile: fileData,
})
}
})
Since return is occuring in the callback , you should use local var and push the data