FormData in React Native throws blank object - javascript

In my React Native project i'm using react-native-image-picker for image upload. Here, i am using formData to upload image. Image URL is there, but when i console the formData it shows {}. I don't know why this is happening. Here's the code :
uploadImageAsync = async (imgUri, token) => {
let apiUrl = 'url';
let formData = new FormData();
let uriParts = imgUri.split('.');
let fileType = uriParts[uriParts.length - 1];
//generate some random number for the filename
var randNumber1 = Math.floor(Math.random() * 100);
var randNumber2 = Math.floor(Math.random() * 100);
formData.append('image', {
uri: imgUri,
name: `photo-${randNumber1}-${randNumber2}.${fileType}`,
type: `image/${fileType}`,
});
console.log('formData :', formData);
let options = {
method: 'POST',
body: formData,
headers: {
Accept: 'application/json',
Authorization: 'Bearer ' + token,
'Content-Type': 'multipart/form-data',
'Cache-Control': 'no-cache',
},
};
const response = await fetch(apiUrl, options);
const json = await response.json();
}
};
Console of formData shows no data but imgUri consists image path. Why formData is showing no data?

The value property of FormData.append() can be either a USVString or a Blob.
Therefore, you can try stringifying your object and then optionally parse the string data.
const imageData = {
uri: imgUri,
name: `photo-${randNumber1}-${randNumber2}.${fileType}`,
type: `image/${fileType}`,
};
const formData = new FormData();
formData.append("image", JSON.stringify(imageData));
const formImageData = formData.get("image");
const parsedFormImageData = JSON.parse(formImageData);
console.log(parsedFormImageData );

Related

Node axios not sending correct header: 'Content-Type': 'multipart/form-data'

I am attempting to upload a file using the Node example provided in the HubSpot docs.
I am receiving 415(Unsupported media type). The response says I am sending the header application/json even though I am setting multipart/form-data.
const uploadFile = async () => {
const postUrl = `https://api.hubapi.com/filemanager/api/v3/files/upload?hapikey=${HAPI_KEY}`;
const filename = `${APP_ROOT}/src/Files/Deal/4iG_-_CSM_Additional_Capacity/test.txt`;
const headers = {
'Content-Type': 'multipart/form-data'
}
var fileOptions = {
access: 'PUBLIC_INDEXABLE',
overwrite: false,
duplicateValidationStrategy: 'NONE',
duplicateValidationScope: 'ENTIRE_PORTAL'
};
var formData = {
file: fs.createReadStream(filename),
options: JSON.stringify(fileOptions),
folderPath: '/Root'
};
try {
const resp = await axios.post(postUrl, formData, headers); // API request
console.log(resp.data)
} catch (error) {
console.log("Error: ", error);
}
}
Can you see what the problem is or recommend a better way of uploading the file?
Thanks!
The Node example you link to uses the (deprecated) request module, not Axios.
To use Axios (source) you would rewrite that as:
const FormData = require('form-data');
const form = new FormData();
form.append('file', fs.createReadStream(filename));
form.append('options', JSON.stringify(fileOptions));
form.append('folderPath', '/Root');
const config = { headers: form.getHeaders() };
axios.post(postUrl, form, config);
We can Run API in Postman and check NodeJs - Axios Detail in Postman Code Snippet and I Think That's the Better way for this.
const axios = require('axios');
const FormData = require('form-data');
const fs = require('fs');
const uploadFile = async () => {
try {
let data = new FormData();
data.append('folderPath', '/Root');
form.append('file', fs.createReadStream(`${APP_ROOT}/src/Files/Deal/4iG_-_CSM_Additional_Capacity/test.txt`));
data.append('options', JSON.stringify({
access: 'PUBLIC_INDEXABLE',
overwrite: false,
duplicateValidationStrategy: 'NONE',
duplicateValidationScope: 'ENTIRE_PORTAL'
}));
var config = {
method: 'post',
url: `https://api.hubapi.com/filemanager/api/v3/files/upload?hapikey=${HAPI_KEY}`,
headers: {
'Content-Type': 'multipart/form-data'
},
data: data
};
const resp = await axios(config); // API request
console.log(resp.data)
} catch (error) {
// error
}
}

How to attach file in the body while using fetch(for calling api) in react native

Hi I am new to React Native, and I was trying to call my API hosted on Heroku my code is below:
const path = RNFS.ExternalDirectoryPath + '/newFile.jpg';
const handleUploadFile = async () => {
const token = await AsyncStorage.getItem('authtoken')
const file = await RNFS.readFile(path, "base64");
let url = `${host}/api/docs/add?card=${value}&number=${myFileId}`;
console.log(url);
let imageData = {
uri: path,
type: 'image/jpg', //the mime type of the file
name: 'newFile'
}
let formData = new FormData();
formData.append('file', imageData);
const response = await fetch(url, {
method: 'POST',
mode: 'cors',
cache: 'no-cache',
credentials: 'same-origin',
headers: {
'authtoken': token,
'Content-Type': 'multipart/form-data'
},
body: formData
});
const output = await response.json();
console.log(output);
}
And while programming the server-side I tested my code as
But while calling API from react-native I was getting the below error:
Please help me in uploading file.
after you reciving the file as base64 you should convert it to a file and after that you can append it to your formData:
const base64File = await RNFS.readFile(path, "base64");
const blobResult = await fetch(base64File);
const file = new File([blobResult], "newFile",{ type: "image/jpg" });
const formData = new FormData();
formData.append('file', file);

Updating Blob Name

I'm having an issue Updating a blobs name - I have done this no problem before but in this case I'm storing the blob in IndexedDB and based on certain conditions (save/saveas) it gets a name from Google Drive or you can add a new name.
Dom JS File
//Convert Text to Blob
let file = text;
fileName = "NewFileName";
let metadata = {
name: fileName, // Filename
mimeType: "application/pdf", // mimeType at Google Drive
};
let form = new FormData();
form.append(
"metadata",
new Blob([JSON.stringify(metadata)], { type: "application/json" })
);
form.append("file", file);
let textBlob = new Blob([file], {
'type': 'application/pdf',
});
Then My ServiceWorker Receives it and renames it then uploads it to google Drive
let blobPDF = request.result.text;
let blob = new Blob([blobPDF], {
type: "application/pdf"
});
let newBlob = new FormData();
console.log("Blob Name : " + saveas)
//Set New Name
newBlob.append("blob", blob, saveas);
fetch(
"https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&fields=id",
{
method: "POST",
headers: new Headers({ Authorization: "Bearer " + accessToken }),
body: blob // Also tried newBlob var -> Got not a blob error
}
)
if I use the var newBlob it says it's not a blob and errors - then changed to "file" it still doesn't set name
One obvious mistake is that you're sending the blob itself as the body of your fetch request, not the newBlob form data object with the filename.
fetch("https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&fields=id", {
method: "POST",
headers: new Headers({ Authorization: "Bearer " + accessToken }),
body: newBlob
// ^^^^
})
If that doesn't help, I'd try creating a File instead of a Blob:
let blob = new File([blobPDF], saveas, {
type: "application/pdf"
});

How to convert a readable stream to a blob in javascript?

I have a test that should read a image file and submit the image file to an api that accepts a multipart-formdata.
I am using the fetch api along with formdata class to set the image file. The formdata only accepts a blob. So in my test i must convert the the file i read in which is of type stream to a blob.
test("should submit front document", async () => {
const side = "front";
const stream = fs.createReadStream(process.cwd() + "/test/resources/" + "id/front.jpg");
const image = await streamToBlob(stream);
const front = await myLibrary.document(id, side, image);
expect(front.success).toBe(true);
});
I am attempting to use a library here to convert the stream to a blob https://www.npmjs.com/package/stream-to-blob. However the test is failing. If i attempt to console.log(image) i get the following Blob {}
Why is the blob empty {}?
async document(id, side, image) {
const url = this.API_URL + "/document"
let formData = new FormData();
formData.set("image", image, "front.jpg");
formData.set("side", side);
let headers = new Headers();
headers.set("Authorization", "Bearer " + this.API_KEY);
const request = {
method: "POST",
body: formData,
headers: headers,
};
try {
const response = await fetch(url, request);
const data = await response.json();
return data;
} catch (err) {
throw err;
}
}

Axios error Data after transformation must be a string, an ArrayBuffer, a Buffer, or a Stream

I'm getting this error when trying to do a POST request using axios:
Error: Data after transformation must be a string, an ArrayBuffer, a Buffer, or a Stream at createError
Here's my request:
async function fetchAndHandleErrors() {
const url = `/claim/${claimId}`;
const headers = {
Accept: 'application/json',
Authorization: `Bearer ${token}`,
};
const body = new FormData();
body.append('damage_description', damageDescription);
body.append('damaged_phone', {
uri: imageUri,
type: 'image/jpeg', // or photo.type
name: imageUri,
});
const result = await axios({
'post',
url: `${baseUrl}${url}`,
data: body,
headers,
});
return result.data;
}
I tried removing result.data and still get the same error. Why is that?
If you eventually still need a solution for this, I managed to get rid of this error by using the formData.pipe() method. For your case, it could look like this :
import axios from 'axios'
import concat from 'concat-stream'
import fs from 'fs'
import FormData from 'form-data'
async function fetchAndHandleErrors() {
const file = fs.createReadStream(imageUri)
let body = new FormData();
body.append('damage_description', damageDescription);
body.append('damaged_phone', file);
body.pipe(concat(data => {
const url = `/claim/${claimId}`;
const headers = {
'Authorization': `Bearer ${token}`,
...body.getHeaders()
};
const result = await axios({
'post',
url: `${baseUrl}${url}`,
data: body,
headers,
});
return result.data;
}))
}
Please let me know if you still encounters your issue, I'll be glad to help !

Categories