432

I'm parsing some data using a type class in my controller. I'm getting data as follows:

{  
   "data":{  
      "userList":[  
         {  
            "id":1,
            "name":"soni"
         }
      ]
   },
   "status":200,
   "config":{  
      "method":"POST",
      "transformRequest":[  
         null
      ],
      "transformResponse":[  
         null
      ],
      "url":"/home/main/module/userlist",
      "headers":{  
         "rt":"ajax",
         "Tenant":"Id:null",
         "Access-Handler":"Authorization:null",
         "Accept":"application/json, text/plain, */*"
      }
   },
   "statusText":"OK"
}

I tried to store the data like this

var userData = _data;
var newData = JSON.parse(userData).data.userList;

How can I extract the user list to a new variable?

Srdjan Pazin
  • 103
  • 2
  • 5
Soniya Mohan
  • 4,514
  • 2
  • 12
  • 14

10 Answers10

553

The JSON you posted looks fine, however in your code, it is most likely not a JSON string anymore, but already a JavaScript object. This means, no more parsing is necessary.

You can test this yourself, e.g. in Chrome's console:

new Object().toString()
// "[object Object]"

JSON.parse(new Object())
// Uncaught SyntaxError: Unexpected token o in JSON at position 1

JSON.parse("[object Object]")
// Uncaught SyntaxError: Unexpected token o in JSON at position 1

JSON.parse() converts the input into a string. The toString() method of JavaScript objects by default returns [object Object], resulting in the observed behavior.

Try the following instead:

var newData = userData.data.userList;
TimoStaudinger
  • 41,396
  • 16
  • 88
  • 94
  • 1
    So it this applicable for all kinds of browsers ? – AdityaKapreShrewsburyBoston Jun 12 '17 at 18:51
  • @Timo Could you look this link. – Varun Sharma Nov 15 '17 at 05:38
  • Sometimes this error can surface when the api url endpoint that serves the request has an error in its code or some other included or used file and it throws a error which is not handled or noted. Mostly you can get this if you look at the network tab in Browser developer tools or you can hit the endpoint using post man and see what comes up. – MuturiAlex May 23 '20 at 16:54
  • Thank you for the explanation on the JSON String vs JS Obj distinction, easier to remember how to do it right when you know why it happened. – BrettJ Oct 26 '20 at 04:49
  • Saved me a few minutes, thanks. I was using require. – Robert Moskal Dec 14 '21 at 19:22
  • 1
    In express I was doing JSON.parse(response.data) which I had forgot was already parsed into json object hence causing this error. – Emile Jan 22 '22 at 10:52
211

The first parameter of the JSON.parse function is expected to be a string, and your data is a JavaScript object, so it will coerce it to the string "[object Object]". You should use JSON.stringify before passing the data:

JSON.parse(JSON.stringify(userData))
Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75
huruji
  • 2,159
  • 1
  • 7
  • 3
  • 3
    this will not work when the string contains a double quote do you have any solution – Mr Coder Jun 08 '20 at 13:29
  • 17
    Maybe I'm missing something obvious, but why would you turn an object into JSON (which is what `JSON.stringify()` does), only to parse the JSON back into an object? Why not use the object directly? This seems completely superfluous. – Ivar Aug 25 '20 at 13:44
  • Probably not the example from the OP - but sometimes you need the JSON structure and not JavaScript one for some libraries. This helped. – G. Urikh Sep 24 '21 at 13:20
  • 1
    If you need JSON then you **wouldn't** use `JSON.parse` since that turns the JSON back into JS. – Quentin Jan 24 '22 at 14:50
51

Don't ever use JSON.parse without wrapping it in try-catch block:

// payload 
let userData = null;

try {
    // Parse a JSON
    userData = JSON.parse(payload); 
} catch (e) {
    // You can read e for more info
    // Let's assume the error is that we already have parsed the payload
    // So just return that
    userData = payload;
}

// Now userData is the parsed result
calvin11
  • 187
  • 1
  • 17
Kousha
  • 32,871
  • 51
  • 172
  • 296
28

Just above JSON.parse, use:

var newData = JSON.stringify(userData)
bruntime
  • 371
  • 2
  • 13
Sukhchain
  • 367
  • 3
  • 4
  • 12
    `JSON.stringify()` converts a JavaScript object to a string representation of it, which is the opposite of what `JSON.parse()` does. You were getting the `SyntaxError` because you were trying to parse something that was already an object. In @Sukhchain's solution, it gets converted to a string to avoid that. – Hubert Oct 03 '17 at 18:54
  • 1
    The downside of that is, in the end you're using `JSON.parse()` too much redundantly. Even though it's a pretty fast process, parsing JSON is done synchronously and can potentially block your UI, so I'd advise against using that. Instead, you could check if your variable is an object, for example using `typeof(userData) === 'object'` before attempting to parse it. – Hubert Oct 03 '17 at 18:54
10

We can also add checks like this:

function parseData(data) {
    if (!data) return {};
    if (typeof data === 'object') return data;
    if (typeof data === 'string') return JSON.parse(data);

    return {};
}
Pulkit chadha
  • 816
  • 11
  • 14
6

You can simply check the typeof userData & JSON.parse() it only if it's string:

var userData = _data;
var newData;
if (typeof userData === 'object')
  newData = userData.data.userList; // dont parse if its object
else if (typeof userData === 'string')
  newData = JSON.parse(userData).data.userList; // parse if its string
deadcoder0904
  • 7,232
  • 12
  • 66
  • 163
3

Unexpected 'O' error is thrown when JSON data or String happens to get parsed.

If it's string, it's already stringfied. Parsing ends up with Unexpected 'O' error.

I faced similar( although in different context), I solved the following error by removing JSON Producer.

    @POST
    @Produces({ **MediaType.APPLICATION_JSON**})
    public Response login(@QueryParam("agentID") String agentID , Officer aOffcr ) {
      return Response.status(200).entity("OK").build();

  }

The response contains "OK" string return. The annotation marked as @Produces({ **MediaType.APPLICATION_JSON})** tries to parse the string to JSON format which results in Unexpected 'O'.

Removing @Produces({ MediaType.APPLICATION_JSON}) works fine. Output : OK

Beware: Also, on client side, if you make ajax request and use JSON.parse("OK"), it throws Unexpected token 'O'

O is the first letter of the string

JSON.parse(object) compares with jQuery.parseJSON(object);

JSON.parse('{ "name":"Yergalem", "city":"Dover"}'); --- Works Fine

Yergalem
  • 1,603
  • 18
  • 14
3

The reason for the error is Object is not in the form of string, it is {} and it should be string Object('{}')

KARTHIKEYAN.A
  • 18,210
  • 6
  • 124
  • 133
0

Give a try catch like this, this will parse it if its stringified or else will take the default value

let example;
   try {
   example  = JSON.parse(data)
  } catch(e) {
    example = data
  }
Pran R.V
  • 1,015
  • 12
  • 21
-1

First set request value in variable like:

let reqData = req.body.reqData;
if (reqData) {
  let reqDataValue = JSON.parse(JSON.stringify(reqData));
}
Mario Petrovic
  • 7,500
  • 14
  • 42
  • 62