Convert JSON flattened for forms back to an object
- by George Jempty
I am required (please therefore no nit-picking the requirement, I've already nit-picked it, and this is the req) to convert certain form fields that have "object nesting" embedded in the field names, back to the object(s) themselves. Below are some typical form field names:
phones_0_patientPhoneTypeId
phones_0_phone
phones_1_patientPhoneTypeId
phones_1_phone
The form fields above were derived from an object such as the one toward the bottom (see "Data"), and that is the format of the object I need to reassemble. It can be assumed that any form field with a name that contains the underscore _ character needs to undergo this conversion. Also that the segment of the form field between underscores, if numeric, signifies a Javascript array, otherwise an object.
I found it easy to devise a (somewhat naive) implementation for the "flattening" of the original object for use by the form, but am struggling going in the other direction; below the object/data below I'm pasting my current attempt. One problem (perhaps the only one?) with it is that it does not currently properly account for array indexes, but this might be tricky because the object will subsequently be encoded as JSON, which will not account for sparse arrays. So if "phones_1" exists, but "phones_0" does not, I would nevertheless like to ensure that a slot exists for phones[0] even if that value is null.
Implementations that tweak what I have begun, or are entirely different, encouraged. If interested let me know if you'd like to see my code for the "flattening" part that is working. Thanks in advance
Data:
var obj = {
phones: [{
"patientPhoneTypeId": 4,
"phone": "8005551212"
},
{
"patientPhoneTypeId": 2,
"phone": "8885551212"
}]};
Code to date:
var unflattened = {};
for (var prop in values) {
if (prop.indexOf('_') > -1) {
var lastUnderbarPos = prop.lastIndexOf('_');
var nestedProp = prop.substr(lastUnderbarPos + 1);
var nesting = prop.substr(0, lastUnderbarPos).split("_");
var nestedRef, isArray, isObject;
for (var i=0, n=nesting.length; i<n; i++) {
if (i===0) {
nestedRef = unflattened;
}
if (i < (n-1)) { // not last
if (/^\d+$/.test(nesting[i+1])) {
isArray = true;
isObject = false;
}
else {
isArray = true;
isObject = false;
}
var currProp = nesting[i];
if (!nestedRef[currProp]) {
if (isArray) {
nestedRef[currProp] = [];
}
else if (isObject) {
nestedRef[currProp] = {};
}
}
nestedRef = nestedRef[currProp];
}
else {
nestedRef[nestedProp] = values[prop];
}
}
}