Wondering what’s next for npm?Check out our public roadmap! »

    @tsmx/json-traverse

    1.0.4 • Public • Published

    @tsmx/json-traverse

    License: MIT npm (scoped) node-current (scoped) Build Status Coverage Status

    Traverse and manipulate JSON objects.

    Usage

    Basic usage

    const jt = require('@tsmx/json-traverse');
    
    const callbacks = {
        processValue: (key, value, level, path, isObjectRoot, isArrayElement, cbSetValue) => { 
                /* your logic here */ 
            },
        enterLevel: (level, path) => { 
                /* your logic here */ 
            },
        exitLevel: (level, path) => { 
                /* your logic here */ 
            }
    };
    
    var obj = { /* your JSON object */ };
    
    jt.traverse(obj, callbacks);

    Example 1: print out a simple object

    var simpleObj = {
        MyValue: 'test',
        OtherValue: 'zzz',
        NumberValue: 311,
        MyArray: [1, 2, 3, 50, 60, 70]
    };
    
    const callbacks = {
        processValue: (key, value, level, path, isObjectRoot, isArrayElement, cbSetValue) => { 
            console.log(level + ' ' + (path.length > 0 ? (path.join('.') + '.') : '') + key + ' = ' + value); 
        }
    };
    
    const jt = require('@tsmx/json-traverse');
    
    jt.traverse(simpleObj, callbacks);
    // 0 MyValue = test
    // 0 OtherValue = xxx
    // 0 NumberValue = 311
    // 0 MyArray._0 = 1
    // 0 MyArray._1 = 2
    // 0 MyArray._2 = 3
    // 0 MyArray._3 = 50
    // 0 MyArray._4 = 60
    // 0 MyArray._5 = 70
    
    // flat array-mode: flattenArray = true (arrays are treated as one value)
    jt.traverse(simpleObj, callbacks, true);
    // 0 MyValue = test
    // 0 OtherValue = xxx
    // 0 NumberValue = 311
    // 0 MyArray = 1,2,3,50,60,70

    Example 2: change values of an object

    var simpleObj = {
        MyValue: 'test',
        OtherValue: 'zzz',
        NumberValue: 311,
        MyArray: [1, 2, 3, 50, 60, 70]
    };
    
    const callbacks = {
        processValue: (key, value, level, path, isObjectRoot, isArrayElement, cbSetValue) => { 
            // change values of properties starting with 'My' and
            // multiply all numeric array values greater then 50 by 100
            if (key.startsWith('My')) {
                cbSetValue('MyNew-' + value);
            }
            if (isArrayElement && parseInt(value) > 50) {
                cbSetValue(100 * parseInt(value));
            }
        }
    };
    
    const jt = require('@tsmx/json-traverse');
    
    jt.traverse(simpleObj, callbacks);
    
    // {
    //   MyValue : "MyNew-test",
    //   OtherValue: "xxx",
    //   NumberValue: 311,
    //   MyArray: [ 1, 2, 3, 50, 6000, 7000 ]
    // }

    Example 3: convert a more complex object to a collapsible HTML list

    var htmlObj = {
        MyArray: [0, 0],
        ArrayInArray: [0, 1, ['two', 'three', [4, 5, 6]]],
        MyNumber: 123,
        MyString: 'test',
        Child: {
            ChildVal: 1,
            SubChild: {
                SubChildVal: 777
            },
            ChildArray: [1, 2, 66, 9, 900]
        },
        TrailingValue: 'testtesttest'
    }
    
    const callbacksHtmlList = {
        processValue: (key, value, level, path, isObjectRoot, isArrayElement, cbSetValue) => {
            if (isObjectRoot) {
                console.log(('  ').repeat(level) + ' <li class=\"caret\">Key: ' + key + '</li>')
            }
            else {
                console.log(('  ').repeat(level) + ' <li>Key: ' + key + ', Value: ' + value + '</li>')
            };
        },
        enterLevel: (level, path) => {
            if (level == 0) {
                console.log('<ul>');
            }
            else {
                console.log(('  ').repeat(level) + '<ul class=\"nested\">');
            };
        },
        exitLevel: (level, path) => { console.log(('  ').repeat(level) + '</ul>'); }
    };
    
    const jt = require('@tsmx/json-traverse');
    
    jt.traverse(htmlObj, callbacksHtmlList, true);
    
    // <ul>
    //  <li>Key: MyArray, Value: 0,0</li>
    //  <li>Key: ArrayInArray, Value: 0,1,two,three,4,5,6</li>
    //  <li>Key: MyNumber, Value: 123</li>
    //  <li>Key: MyString, Value: test</li>
    //  <li class="caret">Key: Child</li>
    //   <ul class="nested">
    //    <li>Key: ChildVal, Value: 1</li>
    //    <li class="caret">Key: SubChild</li>
    //     <ul class="nested">
    //      <li>Key: SubChildVal, Value: 777</li>
    //     </ul>
    //    <li>Key: ChildArray, Value: 1,2,66,9,900</li>
    //   </ul>
    //  <li>Key: TrailingValue, Value: testtesttest</li>
    // </ul>

    Key-features

    • Define your callbacks for the following events:
      • processValue: processing a traversed value
      • enterLevel: entering a new nesting level
      • exitLevel: leaving nesting level
    • For every inspected value you will get rich meta-data
      • key name
      • level of nesting
      • isObjectRoot flag to indicate if it's an object root (root of a nested object)
      • isArrayElement flag to indicate if it's an array item
      • full path to the key as an array of path elements
    • Provides cbSetValue function to change any value in-place (directly in the traversed object)
    • Supports deep inspection of
      • Subobjects
      • Arrays
      • Arrays-in-Arrays
      • Subobjects-in-Arrays
    • Optional array flattening (treat arrays as flat values)

    API

    traverse(obj, callbacks = null, flattenArray = false)

    Traverse the obj and apply the defined callbacks while traversing.

    obj

    Type: Object

    The object to be traversed.

    callbacks

    Type: Object Default: null

    An Object containing the callback functions that should be applied while traversing obj. Every callback is optional. The expected form is:

    callbacks = {
        processValue: (key, value, level, path, isObjectRoot, isArrayElement, cbSetValue) => { 
                /* your logic here */ 
            },
        enterLevel: (level, path) => { 
                /* your logic here */ 
            },
        exitLevel: (level, path) => { 
                /* your logic here */ 
            }
    };
    processValue(key, value, level, path, isObjectRoot, isArrayElement, cbSetValue)

    Defined callback function that is executed on each value when traversing the object. Receives the following input parameters:

    key

    Type: String

    The key of the current value that is processed. If an array is deep-inspected the key for each processed item is _ + Index (_0, _1, _2,...).

    value

    Type: String

    The actual value for key.

    level

    Type: Number

    The nesting level. 0 indicates the first level.

    path

    Type: Array

    An array containing all keys that where passed to reach the current key/value pair. Example:

    {
        child: {
            subchild: {
                myvalue: 123;
            }
        }
    }

    When processing the value 123 with key myvalue, path would be ['child', 'subchild' ].

    For deep-inspected arrays the path would contain the name of the array itself whereas the key would be the index of the processed value. Example:

    {
        child: {
            subchild: {
                myvalues: [1, 2, 3]
            }
        }
    }

    When processing the array the keys would be _0, _1 and _2 and the path would always be ['child', 'subchild', 'myvalues'].

    isObjectRoot

    Type: Boolean

    true if the currently processed key is the root of another sub-object. In our example:

    {
        child: {
            subchild: {
                myvalue: 123;
            }
        }
    }

    isObjectRoot would be true for the keys child and subchild.

    isArrayElement

    Type: Boolean

    true if the currently processed key is an item of an array.

    cbSetValue(newValue)

    Type: Function

    Callback function receiving the newValue that should replace the currently traversed value.

    Note: Setting a new value directly changes the traversed object! So if you need the original later on be sure to create a copy of the object first.

    enterLevel(level, path)

    Defined callback function that is executed on entering a new nesting level when traversing the object. Receives the following input parameters:

    level

    Type: Number

    0-based index of the nesting level that is entered.

    path

    Type: Array

    An array containing all keys that where passed to reach the current level that is entered.

    exitLevel(level, path)

    Defined callback function that is executed on leaving a nesting level when traversing the object. Receives the following input parameters:

    level

    Type: Number

    0-based index of the nesting level that is exited.

    path

    Type: Array

    An array containing all keys that where passed to reach the current level that is exited.

    flattenArray

    Type: Boolean Default: false

    If set to true arrays will not be iterated but treated as one single value. The default is false, where arrays are iterated and each entry is processed separately including deep-inspection, e.g. if the entry is an object or another array.

    Install

    npm i @tsmx/json-traverse

    DownloadsWeekly Downloads

    22

    Version

    1.0.4

    License

    MIT

    Unpacked Size

    23.6 kB

    Total Files

    6

    Last publish

    Collaborators

    • avatar