4

I keep getting this error in this block of code below:

function openWebsocket(url) {
    var ws;
    ws = $websocket(url);
    ws.onOpen(function(event) {
        console.log(' Websocket connection established:', event);
    });
    ws.onMessage(function(message) {
        var userObj   = UserFactory.getUserObject();
        var settings  = userObj.alert_settings;

        // The JSON parsing...
        var parsedMsg = JSON.parse(message.data);
        var alert     = JSON.parse(parsedMsg);
        var date      = new Date(parseFloat(alert.start_epoch+'000'));
        alert.hour    = date.getHours() +':'+date.getMinutes();
        alert.percent_change = Math.round(alert.percent_change);

        var shouldPush = main_alert_filter(settings, alert);
        updateFeed(alerts, shouldPush, alert);
    });
}

I've looked at both Parsing JSON giving "unexpected token o" error and I keep getting "Uncaught SyntaxError: Unexpected token o"

However neither answer helped. Because when I first run JSON.parse(message.data) I get a string back not an Object. So thus I have to run JSON.parse again to finally get a real object back.

enter image description here

This is what message.data looks like:

" "{\"term\": \"\\\"nike\\\"\", \"percent_change\": 125, \"hour\": \"10:9\", \"term_id\": 2890413, \"start_epoch\": 1420474140, \"term_trend_id\": 793950, \"end_epoch\": 1420477740, \"formatted_date_difference\": \"January 5, 2015\", \"tickers\": [\"NKE\", \"$PUM\", \"ADDYY\", \"LULU\", \"UA\", \"HIBB\"], \"twitter_preview\": \"\", \"type\": \"spike\", \"approved\": 1, \"search_preview\": [\"\"]}" "

Now after the first parsing parsedMsg is a string that looks like this:

{"term": "minimum wage +increase", "percent_change": 729, "hour": "9:14", "term_id": 2522115, "start_epoch": 1447168440, "term_trend_id": 657898, "end_epoch": 1447175700, "formatted_date_difference": "November 10, 2015", "tickers": ["$JAB", "$SLCY", "AAL", "AAPL", "ABCD", "ABTL", "ADDYY", "ADM", "AEO", "AFCO", "AHC"......

Finally I need an actual object, so I have to run JSON.parse again to get this:

Object {term: "minimum wage +increase", percent_change: 729, hour: "9:14", term_id: 2522115, start_epoch: 1447168440…}

Another thing to note, I never get that error when I'm stepping through in Chrome. It only happens when I don't have the breakpoint set. Could this be a race condition type issue? Like it tries to JSON.parse something that isn't ready to be parsed?


UPDATE

Ok so sometimes the JSON is invalid apparently and sometimes not, so far I'm doing good without errors with the following snippet, thoughts?

if (typeof alert === 'object') {
    // do nothing...
} else {
    var alert = JSON.parse(alert);
}

Most of the time the alert result of JSON.parse(message.data) is a string so I need the other check to double parse it.

Community
  • 1
  • 1
Leon Gaban
  • 36,509
  • 115
  • 332
  • 529
  • 1
    When I `JSON.parse(...)` your first string (well, a valid subset of it), I get the final object, not the interim string you claim to be getting. If I parse *that* object, I get the error you get... – seairth Jul 25 '16 at 20:32
  • your `parse` JSON is incomplete! please share full JSON result so that we may find the error. – M.Tanzil Jul 25 '16 at 20:37
  • Sorry it is complete, it's just super huge and I didn't want to post the whole thing. – Leon Gaban Jul 25 '16 at 20:38
  • If that initial `"` is actually part of `message.data` (and presumably another matching `"` at the end), then yes, this data is a single string, not a representation of the object you expect. That's why you're having to parse it twice. – Michael Geary Jul 25 '16 at 21:02
  • 1
    Your updated `message.data` can't possibly be the actual data, or is it? It has newlines after the first quote and before the final quote. And those triple-backlashes - is that what's really in the data? – Michael Geary Jul 25 '16 at 21:21
  • 1
    @LeonGaban your updated `message.data` is totally invalid having two ` " ` at the start, its invalid string, parsing to json is far away from it. – M.Tanzil Jul 25 '16 at 21:35
  • @LeonGaban from where did you get your result `message.data`, either the plugin makes that for you, or you creating that format yourself ? – M.Tanzil Jul 26 '16 at 05:08
  • Your `alert` is also an invalid `string` it only sees ` " { " ` and expecting ` ; ` after it, so its a syntax error. – M.Tanzil Jul 26 '16 at 05:25

3 Answers3

3

Why would you parse your json second time, its already been parsed in the first attempt.

Have a look at the snippet

var obj = "{\"term\": \"minimum wage +increase\", \"percent_change\": 729, \"hour\": \"9:14\", \"term_id\": 2522115, \"start_epoch\": 1447168440, \"term_trend_id\": 657898, \"end_epoch\": 1447175700, \"formatted_date_difference\": \"November 10, 2015\", \"tickers\": [\"$JAB\", \"$SLCY\", \"AAL\", \"AAPL\", \"ABCD\", \"ABTL\", \"ADDYY\"]}";
$(function(){
  var data = JSON.parse(obj);
  alert(typeof data);
  console.log(data.tickers[0] +" -> an item in `tickers` array");
  console.log(data.tickers);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
M.Tanzil
  • 1,987
  • 1
  • 12
  • 28
  • I had to parse it a 2nd time, because the first time through it was still `typeof string` So I was getting an error on `alert.user` can't set user to string. – Leon Gaban Jul 25 '16 at 20:54
  • @LeonGaban its type is `object` check the updated `snippet` you can access anything in the object, also once string is parsed to json object its parsed, no need parsing second time, if you still having an issue, you may show us the whole object. Hope this helps :) – M.Tanzil Jul 25 '16 at 21:05
  • Check your browser console, you may find your answer, and you will understand your first formatted json object well... Have a look at that. Thanks – M.Tanzil Jul 25 '16 at 21:10
  • Just updated my question with my full `message.data` JSON – Leon Gaban Jul 25 '16 at 21:17
2

The JSON string you specified with message.data is not a well formed JSON parsed as String. It might be because the server is sending you a multi-part message during/after establishing the connection.

I suggest you print the message object received in OnMessage function and analyze if they are fully formed valid JSON Strings.

Surya
  • 51
  • 2
0

It looks like Your message.data is incomplete.

Take a look on the library docs You are using, maybe you should collect the data until it's end? Maybe there is some onEnd method?

rtbm
  • 536
  • 3
  • 9
  • Sorry it is complete, just super huge so didn't want to post the entire JSON, but I can if need be. – Leon Gaban Jul 25 '16 at 20:38
  • Have You tried to parse response in the inspector's console? IMO it's not possible that You should parse it twice :) Maybe there's some malformed data, like unescaped **"** fe.? – rtbm Jul 25 '16 at 20:47
  • @MarcinBogusz: Sure it's possible, if the original JSON data was stringified twice. For example: `JSON.stringify( JSON.stringify({ "foo": "bar" }) )`. That gives you this string: `"{\"foo\":\"bar\"}"`. (The outer quotes here are _part of the string_, not quotes _enclosing_ the string.) Parsing that once gives you the string (not object) `{"foo":"bar"}`; parsing it a second time gives the original object `{foo: "bar"}`. – Michael Geary Jul 25 '16 at 21:33
  • As another example, `JSON.stringify(true)` returns the string `true`. `JSON.stringify( JSON.stringify(true) )` returns the string `"true"` (again, the quotes here are _part of the string_). Parsing this result once returns the _string_ `true`, and parsing _that_ returns the _boolean_ value `true`, e.g. `JSON.parse( JSON.parse( JSON.stringify( JSON.stringify(true) ) ) )`. – Michael Geary Jul 25 '16 at 21:40