I am working on an edit form for my company and someone on my team decided to change the formatting of our API payload return without consulting the rest of the team and now we are playing catchup.
Since the API called we have to post the value back to the DB are not set up for nested objects, I need to flatten it so I can manipulate the values and submit it.
Here is the new nested structure
{
"status": 1,
"data" : {
"name": "Tank",
"dimensions": "2.0 x 2.5 x 4.0"
}
}
and I need to convert it back to something like this:
{
"status": 1,
"name": "Tank",
"dimensions": "2.0 x 22.5 x 4.0"
}
I found multiple solutions online, but all of them are giving me the same TypeScript error
"for (… in …) statements must be filtered with an if statement"
I am also seeing the a lot of them are embedding the name of for first element in from of its nested element, like this:
{
"status": 1,
"data.name": "Tank",
"data.dimensions": "2.0 x 22.5 x 4.0"
}
Can someone show me how to rewrite this flatten function where it eliminates the TS error and doesn’t append the first level element’s name to its nested elements, leaving me with simple single level object?
Here is my flatten function:
const obj = values;
const flattenObj = (ob) => {
// The object which contains the final result
const result = {};
// loop through the object "ob"
for (const i in ob) {
// We check the type of the i using typeof() function and recursively call the function again
if ((typeof ob[i]) === 'object' && !Array.isArray(ob[i])) {
const temp = flattenObj(ob[i]);
for (const j in temp) {
// Store temp in result
result[i + '.' + j] = temp[j];
}
}
// Else store ob[i] in result directly
else {
result[i] = ob[i];
}
}
return result;
};
console.log(flattenObj(ob));
4
Answers
Try this:
Playground
Some changes from your version:
.hasOwnProperty
conditional check to satisfy the lint ruleob[i]
is truthy, note thattypeof null === 'object'
!Record<string, unknown>
. For truly dynamic objects (like the response from an API call) you won’t know the type. If you narrow the type of the data to a specific schema you could probably use template literal types and generics to make a type-safe more specific return value. I’m still trying to figure that out.Here is the working example:
You could change
to
that way you’re not touching the prototype stuff at all.
This can be done by using a recursive function.
In case the
obj[key]
is a simple value likeobj['status']
, it is added directly to the result object.Otherwise, if the
obj[key]
is an object like the value ofobj['data']
, theflattenJSON
function is called usingobj['data']
as a parameter. Once done, the result is concatenated with the previous result.This function handles multiple nesting as well.
Note: The parentKey is not wanted. Consequently, some keys might be overridden.