Search code examples
javascriptjsonstringify

combining replacer and fields in json.stringify


How would I use white-list of fields and a replace function at the same time when using json.stringify?

explains how to use a field list.

Has an answer for filtering null values: https://stackoverflow.com/a/41116529/1497139

Based on that code snippet i am trying:

var fieldWhiteList=['','x1','x2','children'];

let x = {
  'x1':0,
  'x2':null,
  'x3':"xyz", 
  'x4': null,
   children: [
     { 'x1': 2, 'x3': 5},
     { 'x1': 3, 'x3': 6}
   ]
}

function replacer(key,value) { 
  if (value!==null) {
    if (fieldWhiteList.includes(key)) 
      return value;
  }
}
console.log(JSON.stringify(x, replacer,2));

And the result is:

{
  "x1": 0,
  "children": [
    null,
    null
  ]
}

Which is not what I expected. I would have expected the x1 values for the children to show up and not null values.

How could i achieve the expected result?

see also jsfiddle


Solution

  • By adding some debug output to the fiddle

    function replacer(key,value) { 
      if (value!==null) {
        if (fieldWhiteList.includes(key)) 
          return value;
      }
      console.log('ignoring '+key+'('+typeof (key)+')');
    }
    

    I got the output:

    ignoring x2(string) 
    ignoring x3(string) 
    ignoring x4(string) 
    ignoring 0(string) 
    ignoring 1(string) 
    ignoring 2(string) 
    {
      "x1": 0,
      "children": [
        null,
        null,
        null
      ]
    } 
    

    which showed that potentially the keys can be array indices. In this case they are all numbers from 0 to n in string format so:

    adding a regular expression to match numbers fixed the issue

    function replacer(key,value) { 
      if (value!==null) {
        if (fieldWhiteList.includes(key)) 
          return value;
        if (key.match('[0-9]+'))
          return value;
      }
      console.log('ignoring '+key+'('+typeof (key)+')');
    }
    

    with the expected output:

    ignoring x2(string) 
    ignoring x4(string) 
    {
      "x1": 0,
      "x3": "xyz",
      "children": [
        {
          "x1": 2,
          "x3": 5
        },
        {
          "x1": 3,
          "x3": 6
        },
        {
          "x1": 4,
          "x3": 7
        }
      ]
    }