I get an object as a string. How to convert?

Viewed 112

Using IMAP I receive an email.
But parsing, I get this:

{
  from: [ "name lastname <mygmail@gmail.com>" ],
  date: [ "Mon, 21 Jun 2021 13:41:51 +0500" ],
  subject: [ "hello" ]
}

The catch is that this is a string, not an object at all!
I cannot take advantage of this. How do I convert this string to an object?

JSON.parse() throws an error message:

UnhandledPromiseRejectionWarning: SyntaxError: Unexpected token f in JSON at position 141
4 Answers

You get that error because in JSON notation properties should be enclosed in double quotes like this:

{
  "from": [ "name lastname <mygmail@gmail.com>" ],
  "date": [ "Mon, 21 Jun 2021 13:41:51 +0500" ],
  "subject": [ "hello" ]
}

So, if what you get is a string like what you showed, you'll have to add these double quotes yourself (maybe with a nice and coolio regex)

As others have noted, because this is not JSON, you can't parse it as JSON. What it does appear to be is a JavaScript snippet.

In the past eval(customJavaScriptCode) would have been used for this but it is very insecure so avoid it.

A better and safer (but not bulletproof) way is to run the JavaScript in a sandbox environment. It's hard to break out of that. You do that like this:

  1. Prefix your object with result = , the name doesn't really matter.
  2. Execute the JavaScript in a sandbox.
  3. Get the value of the last statement.
const vm = require('vm');

const script = new vm.Script('result = ' + `{
  from: [ "name lastname <mygmail@gmail.com>" ],
  date: [ "Mon, 21 Jun 2021 13:41:51 +0500" ],
  subject: [ "hello" ]
}`);

const lastStatementResult = script.runInNewContext();

console.log(lastStatementResult.subject[0] == "hello");

You now have the object parsed as JS in a relatively safe way.


If you need more than just the last statement, you can do this like this:

const vm = require('vm');

const script = new vm.Script(`
  var foo = "bar";
  var baz = foo + "123";
`);

const context = {}; // will contain global variables from the script
script.runInNewContext(context);

console.log(context.foo + '123' === context.baz);

I was also running into this issue following the documentation to the letter. The problem is exactly how OP describes, there is a return value from one of Imap's callback functions that is shaped like an object, but does not respond to dot notation, nor JSON.parse/stringify.

The problem was using the suggested inspect property from the util node package. This is what is returning a string shaped like an object that is unusable. Instead, omit the inspect on the values you need to parse.

Original usage (straight from the docs) (bad)

stream.once('end', function() {
  console.log(prefix + 'Parsed header: %s', inspect(Imap.parseHeader(buffer)));
});

My solution (good)

stream.once('end', function() {
  console.log(prefix + 'Parsed header: %s', Imap.parseHeader(buffer));
});

All I did was omit the inspect. I can now assign Imap.parseHeader(buffer) to a variable and manipulate it just like a normal JS object.

I did not understand your question correctly.

Try this

JSON.stringify(JSON.parse(Object))

If error exist, Please describe your issue with more

Related