Here is a true, crazy one-liner that flats the nested object recursively:
const flatten = (obj, roots=[], sep='.') => Object.keys(obj).reduce((memo, prop) => Object.assign({}, memo, Object.prototype.toString.call(obj[prop]) === '[object Object]' ? flatten(obj[prop], roots.concat([prop]), sep) : {[roots.concat([prop]).join(sep)]: obj[prop]}), {})
Multiline version, explained:
// $roots keeps previous parent properties as they will be added as a prefix for each prop.
// $sep is just a preference if you want to seperate nested paths other than dot.
const flatten = (obj, roots = [], sep = '.') => Object
// find props of given object
.keys(obj)
// return an object by iterating props
.reduce((memo, prop) => Object.assign(
// create a new object
{},
// include previously returned object
memo,
Object.prototype.toString.call(obj[prop]) === '[object Object]'
// keep working if value is an object
? flatten(obj[prop], roots.concat([prop]), sep)
// include current prop and value and prefix prop with the roots
: {[roots.concat([prop]).join(sep)]: obj[prop]}
), {})
An example:
const obj = {a: 1, b: 'b', d: {dd: 'Y'}, e: {f: {g: 'g'}}}
const flat = flatten(obj)
{
'a': 1,
'b': 'b',
'd.dd': 'Y',
'e.f.g': 'g'
}
Happy one-liner day!