0

I have the following request body which i need to parse to json. I need to parse a payload field (which is a json with a lot of trash in it) to the proper JSON object (it's a result of console.log(req)):

{ payload: '{\\n  \\"taskDueDate\\": \\"No due\\",\\n  \\"oldTaskMilestone\\": null,\\n  \\"isUpdatedTask\\": \\"true\\",\\n  \\"oldTaskAssignee\\": null,\\n  \\"statusType\\": \\"OPEN\\",\\n  \\"oldTaskVisibility\\": null,\\n  \\"isEstimationUpdated\\": \\"false\\",\\n  \\"invokerEmail\\": \\"mike@domain\\",\\n  \\"oldTaskStatus\\": \\"Resolved\\",\\n  \\"projectId\\": \\"61193\\",\\n  \\"taskContent\\": \\"Add god to monit background processes\\",\\n  \\"taskAssignee\\": \\"Mike B.\\",\\n  \\"invokerId\\": \\"38073\\",\\n  \\"isLabelsUpdated\\": \\"false\\",\\n  \\"taskLabels\\": \\"Improvement\\",\\n  \\"isAssignmentUpdated\\": \\"false\\",\\n  \\"oldTaskEstimation\\": null,\\n  \\"isVisibilityUpdated\\": \\"false\\",\\n  \\"isStatusUpdated\\": \\"true\\",\\n  \\"isMilestoneUpdated\\": \\"false\\",\\n  \\"domain\\": \\"xxx\\",\\n  \\"invokerSmallAvatarURL\\": \\"xxx\\",\\n  \\"invoker\\": \\"Mike B.\\",\\n  \\"taskId\\": \\"33\\",\\n  \\"accountURL\\": \\"xx\\",\\n  \\"taskAuthor\\": \\"Mike B.\\",\\n  \\"isTimeEntryAdded\\": \\"false\\",\\n  \\"unsubscribeURL\\": \\"xxx\\",\\n  \\"oldTaskPriority\\": null,\\n  \\"oldTaskDueDate\\": null,\\n  \\"projectURL\\": \\"xxx\\",\\n  \\"taskMilestone\\": \\"Not planned\\",\\n  \\"taskPriority\\": \\"HIGH\\",\\n  \\"taskTitle\\": \\"Start using god gem\\",\\n  \\"oldTaskLabels\\": null,\\n  \\"isPriorityUpdated\\": \\"false\\",\\n  \\"taskURL\\": \\"xxx\\",\\n  \\"taskStatus\\": \\"Open\\",\\n  \\"subdomain\\": \\"xx\\",\\n  \\"invokerProfileURL\\": \\"xx\\",\\n  \\"statusLabel\\": \\"reopened\\",\\n  \\"taskEstimation\\": \\"Not estimated\\",\\n  \\"isNewTask\\": \\"false\\",\\n  \\"isAttachmentsUpdated\\": \\"false\\",\\n  \\"projectName\\": \\"xx\\",\\n  \\"taskVisibility\\": \\"ALL\\",\\n  \\"isDueDateUpdated\\": \\"false\\"\\n}' }

To do so, i'm using the following code:

payload = req.body['payload']
JSON.parse(payload)

Such code gives me an error:

Syntax error: unexpected token \

What's interesting, when i'll dump a content of payload var to console and past it in Chrome Dev Console using JSON.parse(my_copied_json_string), it works just fine.

Can you please advice me why is that possibly behaving like that and what can i do to understand and fix that strange issue?


JSFiddle demonstrating that issue: http://jsfiddle.net/7PZD9/5/

mbajur
  • 4,406
  • 5
  • 49
  • 79
  • Are you sure that error is coming from JSON.parse, and not from something else in your application? I've just tried, and it parses correctly in node.js. – badsyntax Feb 12 '14 at 16:19
  • I can confirm the same as @badsyntax. I just tried your json string and it parses fine – transient_loop Feb 12 '14 at 16:21
  • Please add a minimal nodejs example that gives the error you're seeing. Hard to answer without code. – secretmike Feb 12 '14 at 16:23
  • I have updated the original question to be more specific, please have a look. – mbajur Feb 12 '14 at 16:27
  • Could the payload prefix be the problem? specifically '=>'. Are you using ruby on rails to create objects? – transient_loop Feb 12 '14 at 16:29
  • Well, to be honest, the provided request body is taken from rails server console (i used it to determine what's the request body of a request sent by a web hook of some web tool i'm using.) That's the original output of my rails server. – mbajur Feb 12 '14 at 16:31
  • it seems to me you are not correctly converting your RoR object to a json string – transient_loop Feb 12 '14 at 16:32
  • Problem is that i'm not the one who formats that request ;) I'm getting it just like that and i can't do anything about it. I've checked how that request looks in node and here it is(`console.log(req)`): https://gist.github.com/mbajur/8959222 . I'm updating the original question. – mbajur Feb 12 '14 at 16:35
  • \\ is not a valid escape sequence in a string outside a json string. JSON =/= javascript. '{\\"foo\\":\\"bar\\"}' is not a string json can parse, '{\"foo\":\"bar\"}' is . – mpm Feb 12 '14 at 16:49
  • Yeah, that's what i've also discovered. But the problem is still there if i'll remove the second backslash: http://jsfiddle.net/7PZD9/2/ – mbajur Feb 12 '14 at 16:58

5 Answers5

1

Here's a jsfiddle that's working: http://jsfiddle.net/7PZD9/7/

I first replaced all the new line characters with blank, then replaced the backslashes with blank. If you might have backslashes inside you strings, you'll need a more robust regex that I'm not capable of writing.

var fixed_backslashes = string.replace(/\\n/g, "");
fixed_backslashes = fixed_backslashes.replace(/\\/g,"")
Colin DeClue
  • 2,194
  • 3
  • 26
  • 47
1

This one does work. It's not the most beautiful because I am filtering several time. Fact is your json string has lots of garbage.

string = '{\\n  \\"taskDueDate\\": \\"No due\\",\\n  \\"oldTaskMilestone\\": null,\\n  \\"isUpdatedTask\\": \\"true\\",\\n  \\"oldTaskAssignee\\": null,\\n  \\"statusType\\": \\"OPEN\\",\\n  \\"oldTaskVisibility\\": null,\\n  \\"isEstimationUpdated\\": \\"false\\",\\n  \\"invokerEmail\\": \\"mike@domain\\",\\n  \\"oldTaskStatus\\": \\"Resolved\\",\\n  \\"projectId\\": \\"61193\\",\\n  \\"taskContent\\": \\"Add god to monit background processes\\",\\n  \\"taskAssignee\\": \\"Mike B.\\",\\n  \\"invokerId\\": \\"38073\\",\\n  \\"isLabelsUpdated\\": \\"false\\",\\n  \\"taskLabels\\": \\"Improvement\\",\\n  \\"isAssignmentUpdated\\": \\"false\\",\\n  \\"oldTaskEstimation\\": null,\\n  \\"isVisibilityUpdated\\": \\"false\\",\\n  \\"isStatusUpdated\\": \\"true\\",\\n  \\"isMilestoneUpdated\\": \\"false\\",\\n  \\"domain\\": \\"xxx\\",\\n  \\"invokerSmallAvatarURL\\": \\"xxx\\",\\n  \\"invoker\\": \\"Mike B.\\",\\n  \\"taskId\\": \\"33\\",\\n  \\"accountURL\\": \\"xx\\",\\n  \\"taskAuthor\\": \\"Mike B.\\",\\n  \\"isTimeEntryAdded\\": \\"false\\",\\n  \\"unsubscribeURL\\": \\"xxx\\",\\n  \\"oldTaskPriority\\": null,\\n  \\"oldTaskDueDate\\": null,\\n  \\"projectURL\\": \\"xxx\\",\\n  \\"taskMilestone\\": \\"Not planned\\",\\n  \\"taskPriority\\": \\"HIGH\\",\\n  \\"taskTitle\\": \\"Start using god gem\\",\\n  \\"oldTaskLabels\\": null,\\n  \\"isPriorityUpdated\\": \\"false\\",\\n  \\"taskURL\\": \\"xxx\\",\\n  \\"taskStatus\\": \\"Open\\",\\n  \\"subdomain\\": \\"xx\\",\\n  \\"invokerProfileURL\\": \\"xx\\",\\n  \\"statusLabel\\": \\"reopened\\",\\n  \\"taskEstimation\\": \\"Not estimated\\",\\n  \\"isNewTask\\": \\"false\\",\\n  \\"isAttachmentsUpdated\\": \\"false\\",\\n  \\"projectName\\": \\"xx\\",\\n  \\"taskVisibility\\": \\"ALL\\",\\n  \\"isDueDateUpdated\\": \\"false\\"\\n}'

fixed_backslashes = string.replace(/([^\/])\/([^\/])/g,"$1//$2")
fixed_backslashes = fixed_backslashes.replace(/\\n/g,"")
fixed_backslashes = fixed_backslashes.replace(/\\/g,"")
console.log(fixed_backslashes)

parsed = JSON.parse(fixed_backslashes)
console.log(parsed)

essentially get rid of all backslashes and newlines.

transient_loop
  • 5,984
  • 15
  • 58
  • 117
1

Your JSON is escaped twice.

If you really need that data to be parsed, you can do it like this:

JSON.parse(JSON.parse('"' + payload + '"'))

alex
  • 11,935
  • 3
  • 30
  • 42
  • i'm marking it as an accepted answer cause it's a one-liner and it's the simplest solution. Thanks to you all guys, you're awsome! :) – mbajur Feb 13 '14 at 06:59
0

It shouldn't be a nodeJS problem; Chrome and nodeJS use the same JavaScript engine so if runs on chrome it should run on nodeJS, as well;

I tried to parse the above JSON string in node via command line and it worked. I think there is something that modifies the above string before it ultimately reached node.

ppoliani
  • 4,792
  • 3
  • 34
  • 62
0

Probably you just need to strip the "payload" => (and its counterpart at the end), so that your string is

"{\n  \"accountURL\": \"https://domain.com\",\n  \"newCommitsCount\": \"1\",\n  \"pushURL\":\"https://domain.com/project/64249/git/source/compare/revisions/0b6438955f2a5a7981fd25cfa5b48fe3fb4c888d,7771e638d1356a14d1dc46f3f5cfaab858370a5e\",\n  \"unsubscribeURL\": \"https://domain.com:443/unsubscribe?token=receiverToken&type=COMMITS&projectId=64249\",\n  \"invokerEmail\": \"email@email.com\",\n  \"projectURL\": \"https://domain.com/project/64249\",\n  \"projectId\": \"64249\",\n  \"afterPushRevision\": \"7771e638d1356a14d1dc46f3f5cfaab858370a5e\",\n  \"invokerId\": \"38074\",\n  \"pushDate\": \"2014-02-11T15:26:36+0000\",\n  \"beforePushRevision\": \"0b6438955f2a5a7981fd25cfa5b48fe3fb4c888d\",\n  \"repositoryURL\": \"git_url\",\n  \"subdomain\": \"subdomain\",\n  \"domain\": \"domain\",\n  \"branch\": \"develop\",\n  \"invokerProfileURL\": \"url\",\n  \"commitsCount\": \"1\",\n  \"invokerSmallAvatarURL\": \"xx\",\n  \"projectName\": \"NAME\",\n  \"invoker\": \"Invoker Name.\",\n  \"commits\": {\"commit\":   {\n    \"revision\": \"7771e638d1356a14d1dc46f3f5cfaab858370a5e\",\n    \"commitMessage\": \"quickfix\",\n    \"committerId\": \"38074\",\n    \"committerEmail\": \"email\",\n    \"committerName\": \"Name.\",\n    \"commitDate\": \"2014-02-11T15:26:27+0000\",\n    \"commitURL\": \"https://domain.com/project/64249/git/source/commit/develop/7771e638d1356a14d1dc46f3f5cfaab858370a5e\"  }}}"
transient_loop
  • 5,984
  • 15
  • 58
  • 117
  • If you can't edit it at source, and you know the format is always the same, try stripping that away in your client before executing JSON.parse() – transient_loop Feb 12 '14 at 16:38
  • i'm sorry, the request body in original question was wrong, i've updated it. – mbajur Feb 12 '14 at 16:41
  • well this string looks very different. why are the backslashes suddenly all escaped? check the string in my response. that one works fine. – transient_loop Feb 12 '14 at 16:48
  • yes, check @ppoliani 's comment in his response about the double slashes – transient_loop Feb 12 '14 at 16:49
  • Well, that's really strange. It looks like, that using `console.log payload['payload`]` is not displaying the double backslashes on the output but they are still there (and they are breaking JSON.parse). I've posted a fiddle under ppoliani answer. – mbajur Feb 12 '14 at 16:55