How can I can convert my JS Object to FormData
?
The reason why I want to do this is, I have an object that I constructed out of the ~100 form field valu
This method convert a JS object to a FormData :
function convertToFormData(params) {
return Object.entries(params)
.reduce((acc, [key, value]) => {
if (Array.isArray(value)) {
value.forEach((v, k) => acc.append(`${key}[${k}]`, value));
} else if (typeof value === 'object' && !(value instanceof File) && !(value instanceof Date)) {
Object.entries(value).forEach((v, k) => acc.append(`${key}[${k}]`, value));
} else {
acc.append(key, value);
}
return acc;
}, new FormData());
}
This function adds all data from object to FormData
ES6 version from @developer033:
function buildFormData(formData, data, parentKey) {
if (data && typeof data === 'object' && !(data instanceof Date) && !(data instanceof File)) {
Object.keys(data).forEach(key => {
buildFormData(formData, data[key], parentKey ? `${parentKey}[${key}]` : key);
});
} else {
const value = data == null ? '' : data;
formData.append(parentKey, value);
}
}
function jsonToFormData(data) {
const formData = new FormData();
buildFormData(formData, data);
return formData;
}
const my_data = {
num: 1,
falseBool: false,
trueBool: true,
empty: '',
und: undefined,
nullable: null,
date: new Date(),
name: 'str',
another_object: {
name: 'my_name',
value: 'whatever'
},
array: [
{
key1: {
name: 'key1'
}
}
]
};
jsonToFormData(my_data)
jQuery version:
function appendFormdata(FormData, data, name){
name = name || '';
if (typeof data === 'object'){
$.each(data, function(index, value){
if (name == ''){
appendFormdata(FormData, value, index);
} else {
appendFormdata(FormData, value, name + '['+index+']');
}
})
} else {
FormData.append(name, data);
}
}
var formData = new FormData(),
your_object = {
name: 'test object',
another_object: {
name: 'and other objects',
value: 'whatever'
}
};
appendFormdata(formData, your_object);
If you have an object, you can easily create a FormData object and append the names and values from that object to formData.
You haven't posted any code, so it's a general example;
var form_data = new FormData();
for ( var key in item ) {
form_data.append(key, item[key]);
}
$.ajax({
url : 'http://example.com/upload.php',
data : form_data,
processData : false,
contentType : false,
type: 'POST'
}).done(function(data){
// do stuff
});
There are more examples in the documentation on MDN
With ES6 and a more functional programming approach @adeneo's answer could looks like this:
function getFormData(object) {
const formData = new FormData();
Object.keys(object).forEach(key => formData.append(key, object[key]));
return formData;
}
And alternatively using .reduce()
and arrow-functions:
const getFormData = object => Object.keys(object).reduce((formData, key) => {
formData.append(key, object[key]);
return formData;
}, new FormData());
const buildFormData = (formData: FormData, data: FormVal, parentKey?: string) => {
if (isArray(data)) {
data.forEach((el) => {
buildFormData(formData, el, parentKey)
})
} else if (typeof data === "object" && !(data instanceof File)) {
Object.keys(data).forEach((key) => {
buildFormData(formData, (data as FormDataNest)[key], parentKey ? `${parentKey}.${key}` : key)
})
} else {
if (isNil(data)) {
return
}
let value = typeof data === "boolean" || typeof data === "number" ? data.toString() : data
formData.append(parentKey as string, value)
}
}
export const getFormData = (data: Record<string, FormDataNest>) => {
const formData = new FormData()
buildFormData(formData, data)
return formData
}
const data = {
filePhotos: imageArray,
}
yourAjaxCall({
...,
data: getFormData(data)
})
Screenshot from Chrome dev tools - Network - Headers:
const data = {
nested: {
a: 1,
b: ["hello", "world"],
c: {
d: 2,
e: ["hello", "world"],
}
}
}
yourAjaxCall({
...,
data: getFormData(data)
})
I used this for Post my object data as Form Data.
const encodeData = require('querystring');
const object = {type: 'Authorization', username: 'test', password: '123456'};
console.log(object);
console.log(encodeData.stringify(object));