-1

As in this question, I want to write a large javascript object as an object literal, not as a string, so I can avoid having to use JSON.parse later. Is there a convenient way to render my object like this:

const myObject = { "someKey": "someValue" };

instead of like this?

const myString = "{ \"someKey\":\"someValue\" }";
const myObject = JSON.parse(myString);

Edit: Sorry, I wasn't clear the first time. I want to write Javascript code to print the object literal to a file. If I use JSON.stringify, I get a string, not a literal.

What I want is something like this function:

function writeObjectLiteral(objectToWrite) {
  const objectAsLiteralString = _.map(objectToWrite, (value, key) => {
    if (Array.isArray(value)) {
      return `${key}:[${value.join(',')}]`;
    }
    if (typeof value === 'object') {
      return `${key}:${writeObjectLiteral(value)}`;
    } else {
      return `${key}:${value}`;
    }
  }).join(',');

  return `{${objectAsLiteralString}}`;
}

const testObject = {
  something: "whatever",
  array: [
    'something',
    'other thing'
  ],
  nestedObj: {
    something: "whatever",
    array: [
      'something',
      'other thing'
    ]
  }
};

fs.writeFileSync(
  'outputFile', 
  'const myObject = ' + writeObjectLiteral(testObject) + ';', 'utf8'
);
Seth
  • 10,198
  • 10
  • 45
  • 68
Tim McMackin
  • 199
  • 1
  • 8
  • 6
    It's exactly as you wrote it. Did you try it? – Pointy Jul 02 '19 at 17:40
  • 1
    What is problem in writing JS object ? what is exact question ? – Code Maniac Jul 02 '19 at 17:40
  • Note that while JSON insists that property names be quoted with double-quotes, that is not necessary for property names that are JavaScript identifiers. Also of course values of properties can be any JavaScript type, not just numbers and strings and booleans. – Pointy Jul 02 '19 at 17:41
  • are you writing the json manually or are you getting it from a database? – Santiago Hernández Jul 02 '19 at 17:43
  • Phrased another way: Is there way to get a string that contains the literal representation of an object (not the string output of JSON.stringify) so I can print that string to a file? – Tim McMackin Jul 02 '19 at 17:54
  • 3
    This seems a legit question. Given any object like e.g. `{ foo: "bar" }`, how do you (dynamically) get a String containing *exactly* this: `{ foo: "bar" }` – connexo Jul 02 '19 at 18:03
  • I don't get the point of this question. JSON *is* a text representation of an object literal, and since you need a text representation in order to write to a file... why would you reinvent the wheel? – trincot Jul 03 '19 at 06:02
  • @trincot JSON is a text representation of a _subset_ of an object literal. It only supports string, array, and object data type values. There are a slew of other JavaScript data types which are supported in object literals but not in JSON. I think this thread is highlighting the importance of question clarity. Tim is not trying to reinvent the wheel if he requires support for ALL JS data types in his string representation. However if it's just string, array, and object values that are of concern, then `JSON.stringify` handles exactly that. – Seth Jul 03 '19 at 06:08
  • @Seth, I am of course very aware of that, but you are raising issues that are not in the question. For all we know the OP's problem is not with the limited scope of JSON, but with some obscure "I don't want a string" concern. In fact, they say that it works with `JSON.parse`, but just want to avoid that extra call. So evidently, the scope of what JSON can encode is not the problem here. – trincot Jul 03 '19 at 06:18
  • @trincot that is true. Which is why I think this circles back to the concern of clarity, the question could benefit from a bit more of it. – Seth Jul 03 '19 at 06:24

1 Answers1

0

Your proposed solution is along the right path and should do the trick once completed. However it's only accounting for arrays and other objects, which is essentially the JSON specification. In that case I think you actually want to write a JSON object and not a JavaScript object literal.

Despite what your comment suggests, the most idiomatic solution in that case would be to simply use JSON.stringify since it incidentally produces a valid object literal.

Assuming you're on node's latest LTS v10.16.0, the following code will produce a syntactically correct version of the result from your proposed solution.

const testObject = {
  something: "whatever",
  array: [
    'something',
    'other thing'
  ],
  nestedObj: {
    something: "whatever",
    array: [
      'something',
      'other thing'
    ]
  }
};

fs.writeFileSync(
  'test.js', 
  'const myObject = ' + JSON.stringify(testObject) + ';', 'utf8'
);
// Result:
// const myObject = {"something":"whatever","array":["something","other thing"],"nestedObj":{"something":"whatever","array":["something","other thing"]}};

If readability is a concern then I would suggest using:

JSON.stringify(
  testObject, 
  null, // represents the replacer function. (in this case we don't want to alter the data)
  2 // number of spaces to indent
)

// Result:
// const myObject = {
//   "something": "whatever",
//   "array": [
//     "something",
//     "other thing"
//   ],
//   "nestedObj": {
//     "something": "whatever",
//     "array": [
//       "something",
//       "other thing"
//     ]
//   }
// };

As slebetman pointed out in the comments, Firefox prints "{ \"someKey\":\"someValue\" }" in contrast to Node and Chrome which print '{"someKey":"someValue"}'. However each environment's native implementation of JSON.stringify each produce the non-escaped version.

If you're actually in need of writing true JavaScript object literals, then consider extending support for the rest of JavaScript's data types within your proposed solution.

Seth
  • 10,198
  • 10
  • 45
  • 68
  • 1
    Firefox, node and Chrome returns exactly the same string from JSON.stringify(). The difference is only how the console prints it - not the returned string. You can test this by doing `console.log(JSON.stringify(someObject))` – slebetman Jul 03 '19 at 05:42