I'd like to create this structure:
{
"officine_type": "Pharmacie",
"officine_value": 2002626,
"declared_lines": [
{
"ean": 3578835501148,
"qty": 1
},
{
"ean": 3578835502671,
"qty": 2
}
],
"other_value": "my other value"
}
From a serializeArray() with this output:
0: {name: 'declared_lines.0.ean', value: '3578835502244'}
1: {name: 'declared_lines.0.qty', value: '4'}
2: {name: 'declared_lines.1.ean', value: '3578835502220'}
3: {name: 'declared_lines.1.qty', value: '1'}
4: {name: 'declared_lines.2.ean', value: ''}
5: {name: 'declared_lines.2.qty', value: '0'}
6: {name: 'officine_type', value: 'Pharmacy'}
7: {name: 'officine_value', value: '2000461'}
8: {name: 'other_value', value: ''}
I'm struggling on how to push sub-objects in declared_lines
Right now i have this:
let formData = form.serializeArray();
for (let i = 0; i < formData.length; i ) {
if (formData[i]['name'].indexOf('declared_lines') !== 1) {
let inputName = formData[i]['name'].split('.');
let namespace = inputName[0];
let n = inputName[1];
let key = inputName[2];
let subObj = {};
let current = 'declared_lines[' i ']';
let previous = 'declared_lines[' (i-1) ']';
if (obj.hasOwnProperty(namespace) === false) {
obj[namespace] = [];
}
}
obj[formData[i]['name']] = formData[i]['value'];
}
My brain won't go further :(
CodePudding user response:
You could take the name and split it by dot for the path of the new object and the value and build a new object with the given information.
In setValue
, the reduce callback checks if the next key is a stringed numerical value and takes an array as default object instead of an object.
function setValue(object, path, value) {
const last = path.pop();
path
.reduce((o, k, i, kk) => o[k] = o[k] || (isFinite(i 1 in kk ? kk[i 1] : last) ? [] : {}), object)
[last] = value;
return object;
}
const
data = [{ name: 'declared_lines.0.ean', value: '3578835502244' }, { name: 'declared_lines.0.qty', value: '4' }, { name: 'declared_lines.1.ean', value: '3578835502220' }, { name: 'declared_lines.1.qty', value: '1' }, { name: 'declared_lines.2.ean', value: '' }, { name: 'declared_lines.2.qty', value: '0' }, { name: 'officine_type', value: 'Pharmacy' }, { name: 'officine_value', value: '2000461' }, { name: 'other_value', value: '' }],
result = data.reduce(
(object, { name, value }) => setValue(object, name.split('.'), value),
{}
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
CodePudding user response:
Object destructuring and array.reduce can make your code more readable, try:
let formData = [
{name: 'declared_lines.0.ean', value: '3578835502244'},
{name: 'declared_lines.0.qty', value: '4'},
{name: 'declared_lines.1.ean', value: '3578835502220'},
{name: 'declared_lines.1.qty', value: '1'},
{name: 'declared_lines.2.ean', value: ''},
{name: 'declared_lines.2.qty', value: '0'},
{name: 'officine_type', value: 'Pharmacy'},
{name: 'officine_value', value: '2000461'},
{name: 'other_value', value: ''}
];
let output = formData.reduce((acc,cur) => {
let { name, value } = cur;
if(name.indexOf('declared_lines') === -1){
acc[name] = value;
} else {
let [namespace, n, key] = name.split('.');
if(!acc[namespace]) acc[namespace] = [];
if(!acc[namespace][n]) acc[namespace][n] = {};
acc[namespace][n][key] = value;
}
return acc;
}, {});
console.log(output);
In this case reduce starts with an empty object and it loops over your array to process each element (cur
).