diff --git a/README.md b/README.md index 2e4cb3c..1d0c9c7 100644 --- a/README.md +++ b/README.md @@ -158,3 +158,28 @@ flatten({ // 'key3.a': { b: { c: 2 } } // } ``` + +### useToJSON + +When enabled, `flat` will check for objects with a `toJSON` function and use the result of that function as a value instead of flattening the object. This is particularly useful for complex objects like MongoDB's ObjectID which contain several fields but actually make more sense to present them as a string. + +``` javascript +var flatten = require('flat') + +flatten({ + key1: { + keyA: 'valueI', + toJSON: function() { + return 'JSONvalueI' + } + }, + key2: { + keyB: 'valueII' + } +}, { useToJSON: true }) + +// { +// 'key1': 'JSONvalueI', +// 'key2.keyB': 'valueII' +// } +``` diff --git a/index.js b/index.js index ca8904a..7e745aa 100644 --- a/index.js +++ b/index.js @@ -9,6 +9,7 @@ function flatten (target, opts) { var delimiter = opts.delimiter || '.' var maxDepth = opts.maxDepth + var useToJSON = opts.useToJSON var output = {} function step (object, prev, currentDepth) { @@ -23,16 +24,25 @@ function flatten (target, opts) { type === '[object Array]' ) + var toJSONExists = false + var jsonValue = null + if (useToJSON && value === Object(value) && // Check if primitive type + Object.prototype.toString.call(value.toJSON) === '[object Function]') { + jsonValue = value.toJSON() + toJSONExists = true + } + var newKey = prev ? prev + delimiter + key : key - if (!isarray && !isbuffer && isobject && Object.keys(value).length && + if (!isarray && !isbuffer && isobject && !toJSONExists && + Object.keys(value).length && (!opts.maxDepth || currentDepth < maxDepth)) { return step(value, newKey, currentDepth + 1) } - output[newKey] = value + output[newKey] = toJSONExists ? jsonValue : value }) } diff --git a/test/test.js b/test/test.js index 541c9d7..c089e36 100644 --- a/test/test.js +++ b/test/test.js @@ -180,6 +180,29 @@ suite('Flatten', function () { 'hello.0500': 'darkness my old friend' }) }) + + test('Use useToJSON', function () { + assert.deepEqual(flatten({ + hello: { + world: { + again: 'good morning', + toJSON: function () { + return 'good afternoon' + } + } + }, + lorem: { + ipsum: { + dolor: 'good evening' + } + } + }, { + useToJSON: true + }), { + 'hello.world': 'good afternoon', + 'lorem.ipsum.dolor': 'good evening' + }) + }) }) suite('Unflatten', function () {