How To Upload Multiple Images In Angular - javascript

I have a code for uploading a file to an api .. then api respond with a string url..
then I use that url inside a form group object.
now in my template I need to upload many images > then get each url as a parameter then send them with a json object to api . any one know how to do this please ?
here is my component.ts
let image = product['image'];
let prodImage = new FormData();
prodImage.append('file', image);
let fileUrl = `**********************`;
return this.http.post(fileUrl, prodImage, {
headers: new HttpHeaders().set(
'Authorization',
`Bearer ${localStorage.getItem('user-jwt')}`)
}).subscribe(
(res: any) => {
console.log(res.data.url)
product.image_url = res.data.url;
this.productsService.createProduct(product).subscribe(
//sucess
(response: any) => {}
)}
there problem is when I need many images
let imageFr = let image = product['imageFr'];
let imageEn = let image = product['imageEn'];
let imageDe = let image = product['imageDe'];
let prodImageFr = new FormData();
prodImageFr.append('file', imageEn);
let prodImageEn = new FormData();
prodImageEn.append('file', imageEn);
let prodImageDe = new FormData();
prodImageDe.append('file', imageDe);
I don't wanna use many http post requests inside each others .. If there is any other clean solution..
Thanks

Related

Send a byte array to WCF service

I am trying to send a pdf file from javascript to a rest wcf service.
The service expects an array of byte with the following signature
The trick is in the byte array parameter, all the others are working fine
[OperationContract]
[WebInvoke(UriTemplate = "rest/{sessionToken}/ImportNewTemplate?commit={commit}&createApplication={createApplication}&templateName={templateName}&option={option}")]
[CloudMethod(Group = "02. Templates", Description = "Import a new template in the platform.", HelpFile = "ListPaperTemplate.aspx")]
[CloudParameter(Name = "sessionToken", Description = "session token", HelpFile = "ServiceAPIDoc.aspx?q=sessionToken")]
[CloudParameter(Name = "createApplication", Description = "Create a standalone application linked to this template.")]
[CloudParameter(Name = "commit", Description = "Commit the upload ? if true, the template will be imported, else the return just allow you to preview template description.")]
[CloudParameter(Name = "templateName", Description = "Name of the new template. Only valid for single pdf upload. If the files are zipped, the file name in the zip will be used instead")]
[CloudParameter(Name = "templateFile", Description = "Can be a PDF file, or a zip file containing a flat pdf + xml definition", HelpFile = "ServiceAPIDoc.aspx?q=templateFile")]
CloudObjects.TemplateImportation ImportNewTemplate(string sessionToken, bool commit, bool createApplication, byte[] templateFile, string templateName, string option);
this is what I use from the javascript end to send the pdf file
const file = e.target.files[0];
// Encode the file using the FileReader API
const reader = new FileReader();
var fileByteArray = [];
reader.onloadend = async (e) => {
const arrayBuffer = e.target.result,
array = new Uint8Array(arrayBuffer);
for (const a of array) {
console.log(a);
fileByteArray.push(a);
}
let ret = await dispatch('createTemplate', {name: this.newForm.name, pdf:fileByteArray, save:false});
await this.$store.dispatch('hideLoadingScreen')
// Logs data:<type>;base64,wL2dvYWwgbW9yZ...
};
reader.onerror = async () => {
await this.$store.dispatch('hideLoadingScreen')
}
reader.onabort = async () => {
await this.$store.dispatch('hideLoadingScreen')
}
await this.$store.dispatch('showLoadingScreen');
reader.readAsArrayBuffer(file);
And here is the code to send it to the rest service
let url = `${getters.getServiceUrl}ImportNewTemplate?templateName=${name}&commit=${save || true}`
const xhr = new XMLHttpRequest;
xhr.open("POST", url, false);
xhr.setRequestHeader('Content-Type', 'application/json');
let response = await xhr.send(pdf);
However every time I get an error from the service when it tries to deserialise the byte array.
The exception message is 'There was an error deserializing the object of type System.Byte[]. End element 'root' from namespace '' expected.
I have tried a lot of alternatives but nothing works.
Any suggestions are welcome !
Thanks
For those interested, the trick was to add JSON.stringify to the returned array.
So: xhr.send(JSON.stringify(pdf))
would do the trick

Create csv and post as multipart/form-data in JavaScript

How can I create an equivalent code in JavaScript?
Given ['col1', 'col2'] and ['val1', 'val2'] OR 'col1,col2\r\nval1,val2\r\n'
I want to be able to create a csv object without reading/writing to disk and then POST it.
Python:
from io import StringIO
import csv
import requests
f = StringIO()
w = csv.writer(f)
w.writerow(['col1', 'col2'])
w.writerow(['val1', 'val2'])
input_byte = f.getvalue().encode('UTF-8')
headers = {'Content-Type':"multipart/form-data"}
endpoint = "http://localhost:8085/predict"
files = {'file': ('input.csv', input_byte)}
response = requests.post(endpoint, files=files)
Here is my code in JavaScript so far:
let data = [['col1', 'col2'],
['val1', 'val2']];
// convert to csv format
let csvContent = data.map(e => e.join(",")).join("\r\n") + "\r\n";
// I believe FormData object is required to send multipart/form-data
// I do not think I am passing my csv data correctly
let body = new FormData();
let buff = Buffer.from(csvContent, "utf-8");
body.append("file", buff, {filename : 'input.csv'});
let response = await fetch("http://localhost:8085/predict",
{
method: 'POST',
body: body,
headers: {'Content-Type':"multipart/form-data"}
});
EDIT:
I was able to send a csv file but had to write it to a disk first. Is it possible to avoid it?
let data = [['col1', 'col2'],
['val1', 'val2']];
// convert to csv format
let csvContent = data.map(e => e.join(",")).join("\r\n") + "\r\n";
// save a csv file
let path = './files/' + Date.now() + '.csv';
fs.writeFile(path, csvContent, (err) => {
if (err) {
console.error(err);
}
});
let body = new FormData();
// this works :)
// but how can I create a csv buffer without writing to a disk?
body.append("file", fs.createReadStream(path), {filename : 'input.csv'});
let response = await fetch("http://localhost:8085/predict",
{
method: 'POST',
body: body,
});
I was able to solve my question with the following script:
const FormData = require('form-data');
const Readable = require('stream').Readable;
const fetch = require("node-fetch");
let data = [['col1', 'col2'],
['val1', 'val2']];
// convert to csv format
let csvContent = data.map(e => e.join(",")).join("\r\n") + "\r\n";
const stream = Readable.from(csvContent);
let body = new FormData();
body.append("file", stream, {filename : 'input.csv'});
let response = await fetch("http://localhost:8085/predict",
{
method: 'POST',
body: body,
});

How to send both text and binary data in axios post request?

I would need to find a solution to send via a single axios POST request both of the following:
json structure
binary file (excel file)
How can I achieve this?
let files = event.target.files;
const fileReader = new FileReader();
fileReader.readAsText(files[0], null);
fileReader.onload = () => {
this.fileContent = fileReader.result;
let binaryDataForObject = this.fileContent;
let referenceDataStructure = {
textData: textDataForObject,
binaryData: binaryDataForObject,
referenceDataFileExtension: this.referenceDataFileExtension,
userProvidedDataTypes: this.columnTypes
};
}
this.axios
.post(
"http://url,
referenceDataStructure
)
This works technically but on the java side I couldn't figure out, how to decode the binary data (encoded as a string) so that it is treated as an excel file.
Thank You in advance for any meaningful responses.
Lubos.
With simple POST request you can send only up to 1mb of binary data
To send binary and text in one request you should use FormData
Check out this answer for information
Update 14.12
How I managed to do this in my recent project was using FormData
So firstly you need to get file as a blob:
const fileReader = new FileReader()
// Here we will get the file as binary data
fileReader.onload = () => {
const MB = 1000000;
const Blob = new Blob([fileReader.result], {
// This will set the mimetype of the file
type: fileInputRef.current.files[0].type
});
const BlobName = fileInputRef.current.files[0].name;
if (Blob.size > MB) return new Error('File size is to big');
// Initializing form data and passing the file as a param
const formData = new FormData();
// file - field name, this will help you to read file on backend
// Blob - main data to send
// BlobName - name of the file, default it will be name of your input
formData.append('file', Blob, BlobName);
// Append json data
formData.apped('some-key', someValue)
// then just send it as a body with post request
fetch('/api/submit-some-form-with-file', {
method: 'POST',
body: formData
})
// Handle the rest
.then()
}
fileReader.readAsArrayBuffer(fileInputRef.current.files[0])
You can wrap this example in handle submit function in react and like or use it as is

How can i upload files to file.io using cloud flare workers[javascript]?

These recent days I tryed multiple times to upload file to file.io using cfworkers but it returns error this is my source code:
async function handleRequest() {
const file = fetch('https://upload.wikimedia.org/wikipedia/commons/thumb/b/b1/02_start_book_creator.png/640px-02_start_book_creator.png');
let formData = new FormData();
formData.append("file", file);
var returned=fetch('https://file.io', {
method: 'POST',
body: formData
});
return returned
}
addEventListener("fetch", event => {
return event.respondWith(handleRequest())
})
The error is this:
{"success":false,"error":400,"message":"Trouble uploading file"}
What i have to do with this?
Unfortunately, as of this writing, Cloudflare Workers doesn't support the File API and thus can't construct FormData containing filenames and types, which is probably what you need here.
However, coincidentally, we're planning to roll out support for this very soon -- this week or next week. Once we've done that, you can construct your FormData containing File objects, like so:
let response = await fetch('https://upload.wikimedia.org/wikipedia/commons/thumb/b/b1/02_start_book_creator.png/640px-02_start_book_creator.png');
let data = await response.arrayBuffer();
let file = new File([data], "640px-02_start_book_creator.png", {type: "image/png"})
let formData = new FormData();
formData.append("file", file);

How to send additonal data along with form data in angular

I am sending attached files/images with formData to back end along with content of the mail and then inject them into nodemailer, I am using multer as a middleware if it helps
component.ts
let fileList: FileList = event.target.files;
if(fileList.length > 0) {
this.formData = new FormData();
for(let i = 0 ; i < fileList.length; i++){
let file: File = fileList[i];
this.formData.append('uploadFile', file, file.name);
}
}
service.ts(this works and I can fetch files from req.files in the node)
sendData(formData){
let headers = new HttpHeaders();
return this.http.post('http://localhost:3000/mail',formData)
}
service.ts(doesn't work, need to do this)
sendEmail(formData,email){
let data = { data : email , formData : formData}
return this.http.post('http://localhost:3000/mail',data)
}
both req.files and req.body.formData comes undefined in this case,
I tried appending the formdata to the header but I don't know the proper way to append/fetch or maybe it's not possible to.
Node.js Part
var storage = multer.diskStorage({
destination : (req,file, callback)=>{
req.body.path = [];
callback(null, './storage');
},
filename : (req, file ,callback)=>{
let filename = Date.now() + '-' +file.originalname;
req.body.path.push(filename);
callback(null, filename);
app.post('/mail',upload.any(),nodemailer);
nodemailer.js
module.exports = (req,res)={
console.log(req.files); X
//Code Irrelevant for this question
}
For this you have to do it like this :
sendEmail(formData,email){
let headers = new HttpHeaders();
formData.append('email', email);
return this.http.post('http://localhost:3000/mail',formData);
}
Reason, you have to pass the form as multipart and you are trying to
send data as JSON , so it will not receive anything until you pass the
whole thing as above.
sendEmail(formData,email){
let data = { data : email , formData : formData}
return this.http.post('http://localhost:3000/mail',data)
}
as you can see in your function you are sending the JSON.

Categories