-3

I am using a testing framework to try to return {"foo":true,"bar":false,null} but instead am returning {"foo":true,"bar":false,"baz":null}. After checking the value of result at various points, it appears as though although my each loop is being called for all object elements, it is not executing either my attempt to log the final key, or its (final) surrounding punctuation. However, the loop is logging the value and its following comma.

Can anyone help spot that specific bug?

var stringifyJSON = function(val) {
  var result = '';
  //define basic return types
  var primitive = function(value) {
    if (typeof value === "number" || value === null || typeof value === 'boolean') {
      return value;
    } else if (typeof value === "string") {
      return '"' + value + '"';
      // func, undef., symb. null in array AND as primitive, ommit in obj
    } else if (typeof value !== 'object') {
      return 'null';
    }
  };

  //treat objects (and arrays)
  if (typeof val === "object" && val !== null) {
    val instanceof Array ? result += '[' : result += '{';
    _.each(val, function(el, key, col) {
      if (typeof el === "object") {
        //recurse if nested. start off new brackets.
        result += stringifyJSON(el);
        if (key !== val.length - 1) {
          result += ','; ///
        }
        //not nested (base case)
      } else {
        if (val instanceof Array) {
          result += primitive(el);
          if (key !== val.length - 1) {
            result += ',';
          }
        } else { /// objects
          result += '"' + key + '":' + primitive(val[key]) + ','; //this comma is being added but the first half is not.
          //console.log(result);
        }
      }
    });
    //outside loop: remove final comma from objects, add final brackets
    if (val instanceof Array) {
      result += ']'
    } else {
      if (result[result.length - 1] === ',') {
        //console.log(result);
        result = result.slice(0, -1);
        //console.log(result); 
      }
      result += '}';
    }

    //treat primitives
  } else {
    result += primitive(val);
  }
  //console.log(result);
  return result;

};
Toto
  • 89,455
  • 62
  • 89
  • 125
hbrannan
  • 153
  • 1
  • 7

1 Answers1

3

The first test in the _.each loop is wrong. If you have an object nested inside another object, it will just output the nested object, without putting the key before it. Another problem is that you can't use val.length if val is not an array. Finally, when you're displaying the array or object element, you need to recurse, not just use primitive()

_.each(val, function(el, key, col) {
    if (val instanceof Array) {
      result += stringifyJSON(el);
      if (key !== val.length - 1) {
        result += ',';
      }
    } else { /// objects
      result += '"' + key + '":' + stringifyJSON(el) + ','; //this comma is being added but the first half is not.
      //console.log(result);
    }
  }
});
Barmar
  • 741,623
  • 53
  • 500
  • 612