0

On Ajax success im getting the following data in a count variable. Using(snippet of ajax call success):

success: function (count) {
             console.log(count);
         }

And below console.log(count) hold this data as shown in browser console:

{
    '07/12/2017': {
        'day': {'failed': 0, 'success': 3}, 
        'night': {'failed': 0, 'success': 0}
    }, 
    '06/12/2017': {
        'day': {'failed': 2, 'success': 20}, 
        'night': {'failed': 1, 'success': 291}
    }, 
    '05/12/2017': {
        'day': {'failed': 6, 'success': 50}, 
        'night': {'failed': 1, 'success': 51}
    }
}

My issue when i try to access the data(all within the ajax success function), say i have a variable date = '07/12/2017' and i do count[date] i get undefined, but if i manually copy and hardcode the data to count like below then count[date] will return the object inside the corresponding date:

count = {
        '07/12/2017': {
            'day': {'failed': 0, 'success': 3}, 
            'night': {'failed': 0, 'success': 0}
        }, 
        '06/12/2017': {
            'day': {'failed': 2, 'success': 20}, 
            'night': {'failed': 1, 'success': 291}
        }, 
        '05/12/2017': {
            'day': {'failed': 6, 'success': 50}, 
            'night': {'failed': 1, 'success': 51}
        }
    }

Might be something simple but its totally escaping me right now.

Thanks in advance

Alejandro Suarez
  • 149
  • 3
  • 16
  • 2
    *"My issue when i try to access the data(all within the ajax success function), say i have a variable date = '07/12/2017' and i do count[date] i get undefined"* If `count` *really* held that data, then you wouldn't get `undefined`: https://jsfiddle.net/dne4huug/ So use your debugger to set a breakpoint on the first line of the `success` handler and see what `count` *actually* contains. – T.J. Crowder Dec 07 '17 at 15:13
  • 2
    Most probably you receive `count` as plain string. Do `JSON.parse(count)` before processing it. – dferenc Dec 07 '17 at 15:14
  • 1
    You haven't shown us *where* you try to access `count[date]`, so you could be running into [this problem](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call), but without knowing more I can't be sure. – T.J. Crowder Dec 07 '17 at 15:14
  • 1
    @dferenc - *"Do `JSON.parse(count)` before processing it."* Or better yet, update the server response to correctly identify that you're sending back JSON, and jQuery will do it for you automatically. – T.J. Crowder Dec 07 '17 at 15:15
  • Possible duplicate of [Parse JSON response got from AJAX request through JavaScript](https://stackoverflow.com/questions/14478127/parse-json-response-got-from-ajax-request-through-javascript) – dferenc Dec 07 '17 at 15:16
  • @T.J.Crowder i did, count holds exactly the data i pasted on the second section of code (i check this via `console.log(count);` and copy pasted there) and im only using count within the ajax success function so it should be accessible. If i do `JSON.parse(count)` i get an error: `JSON.parse: expected property name or '}' at line 1 column 2 of the JSON data` – Alejandro Suarez Dec 07 '17 at 15:33
  • @AlejandroSuarez: *"i did, count holds exactly the data i pasted on the second section of code"* Clearly not. If it did, your quoted code would work. *"(i check this via console.log(count);"* Again: Don't stumble around in the dark with a `console.log` torch, *turn on the lights* using your debugger. Something is **slightly** different than you think it is. The sooner as you accept that to be the case, the sooner you'll find your solution. – T.J. Crowder Dec 07 '17 at 15:55
  • It's worth noting that what you've quoted isn't valid JSON. The way it's invalid wouldn't give you the error message you say you've gotten from `JSON.parse` (the message is bizarre, there clearly isn't a `}` at line 1, column 2), but that may be the problem. In JSON, property names (and all other strings) must be in **double** quotes, not single quotes. – T.J. Crowder Dec 07 '17 at 15:58
  • Actually the message is totally right, at position 2 is a single quote and the parser expected either a property name (which would start with a double quote) or a closing brace (in case the object had no properties). It didn't claim there to be an actual closing brace. – CherryDT Apr 21 '20 at 08:33

1 Answers1

2

From the evidence in the question and in the comments, I think count contains a string. What you've shown is invalid JSON and also not how any console I've ever seen represents objects when you console.log them, so I suspect it's a string and it's literally what's coming to your browser from the server.

If so, the server is sending invalid JSON. Property names (and all other strings) must be in double quotes, not single quotes.

So the solution is:

  1. Correct the server's output. The best way to output JSON is not to handcraft it, but instead to build an object graph and then use your server-side environment's equivalent of JSON.stringify.

  2. If you're still receiving a string at that point, update the server code to correctly identify what you're sending back as JSON by having it send this header:

    Content-Type: application/json
    

    jQuery will see that content type on the response and automatically parse the string for you.

Then, count will refer to an object graph, and your code using count[date] where date is the string 07/12/2017 will work.

Here it is working on jsFiddle using jsFiddle's handy "echo" feature which lets us tell the server to echo something back to us: https://jsfiddle.net/narxfmdm/ Here's the code in the fiddle:

var json = '{' +
'    "07/12/2017": {' +
'        "day": {"failed": 0, "success": 3}, ' +
'        "night": {"failed": 0, "success": 0}' +
'    }, ' +
'    "06/12/2017": {' +
'        "day": {"failed": 2, "success": 20}, ' +
'        "night": {"failed": 1, "success": 291}' +
'    }, ' +
'    "05/12/2017": {' +
'        "day": {"failed": 6, "success": 50}, ' +
'        "night": {"failed": 1, "success": 51}' +
'    }' +
'}';
$.ajax({
    type: "POST",
  url: "/echo/json/",
  data: {json: json, delay: 1},
  success: function(count) {
    var date = "07/12/2017";
    $("<p>").text("Data for " + date + ": " + JSON.stringify(count[date])).appendTo(document.body);
  }
});
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • This helped me figure out the issue :). You are 100% right and the key to it was that the server was returning a string that i assume jQuery was parsing as best possible, as already as my python script includes the `Content-Type: application/json` header but it wasnt proper JSON. i had to: `var dataAsStringSwapQuotes = data.replace(/'/g, '"'), dataAsObject = JSON.parse(dataAsStringSwapQuotes);` Now dataAsObject can access all the properties i needed. Thanks a lot – Alejandro Suarez Dec 07 '17 at 16:33
  • 1
    @AlejandroSuarez: Yes, jQuery will have tried to parse it but gotten an error, and so it gives you the unparsed string. Glad that helped, but it would really be best if the Python script were updated to build the structure and then use `json.dumps` to ensure valid JSON is output, rather than having it send invalid JSON. – T.J. Crowder Dec 07 '17 at 16:37
  • Cowder: You know its actually funny, im using json.dumps :)... maybe cause im using python module shelve to store the data instead of an actual json file, this is happening? Who knows... – Alejandro Suarez Dec 07 '17 at 17:09
  • @AlejandroSuarez: I can't imagine how you're inducing `json.dumps` to output what you've said it outputs. I suggest posting a new question showing a [mcve] of your Python code and asking how to fix the fact that it produces invalid JSON. My guess is you'll find that you're not, in fact, using `json.dumps` to produce the output in question. – T.J. Crowder Dec 07 '17 at 17:23