Ask your JavaScript questions! Pay money and get answers fast! (more info)

How do I get this as JSON? JavaScript

Using jQuery, the newest version:



var obj = jQuery.parseJSON('{["buster" {:updated 1348728829383, "username" "buster", "first_name" "Bryson", "last_name" "Arnov", "user_image" ""}]["bill" {:updated 1348728839332, "username" "bill", "first_name" "Bryson", "last_name" "Arnov", "user_image" ""}][nil {:updated 1348728839336}]}');

for(i in obj) {
$('#who_is_logged_in').html(i[0]);
}


In FireFox/FireBug I get:

SyntaxError: JSON.parse: expected property name or '}'

How might I reformat the data, or change the way I parse, so as to get something like JSON or XML, so I can loop over the data and print out each username?

Answers (3)

2012-09-27

Rainner Lins answers:

It's due to the JSON string being malformed, i also tried it with jQuery 1.7.2 and still got the same error.

Try this, I fixed the JSON data and created a simple for loop that looks at each object for a user and prints out info about it.


var output = '';
var obj = $.parseJSON( '{"buster":{"updated":"1348728829383","username":"buster","first_name":"Bryson","last_name":"Arnov","user_image":""},"bill":{"updated":"1348728829383","username":"bill","first_name":"Bryson","last_name":"Arnov","user_image":""},"nil":{"updated":"1348728829383","username":"nil","first_name":"Bryson","last_name":"Arnov","user_image":""}}');

for( var n in obj )
{
var d = obj[n];
output += 'User: ' + d.username + ' is called: ' + d.first_name + ' ' + d.last_name + " \n";
};

alert( output );


Lawrence Krubner comments:

I see, so always with { } and not with [ ] ? I would be happy enough merely to have an array to loop over, but I will try your approach.

2012-09-27

Utkarsh Kukreti answers:

This isn't valid JSON. Where are you getting this data from?


Lawrence Krubner comments:

The data comes from an app that I wrote:

[[LINK href="http://"]]http://www.tailormadeanswers.com:40000/[[/LINK]]

I can change the formatting some. I am looking for suggestions. It is enough to get a Javascript array that I can then loop over. (The end goal is to be able to show who is logged into sites like WP Questions and Javascript Questions. There will be some Javascript on this page (the page that you are now reading) that will ping that URL with your PHP session id, and some code in that app which then checks your session id and lists your personal info if you are really logged in. Then some other Javascript on this page will show who else is logged in. The goal is to move to supporting live chat on these sites.)


Utkarsh Kukreti comments:

What's the code you're using to convert your objects into that string?


Lawrence Krubner comments:

I wrote the main app in Clojure. User data should be stored in an atom called registry. To show it on screeen, I simply turn the map inside of "registry" into a string with "apply str":

(defn current-users [request]
"The default action of this app. Add new users to the registry, and delete the ones that are more than 15 seconds old"
(let [this-users-params (:params request)
final-map-for-output {}]
(add-to-logged-in-registry this-users-params)
(remove-old-registrants)
(response (apply str (doall @registry)))))))

But I can re-write this to output it differently.

2012-09-27

Greger Olsson answers:

Here's an example on how you can do it:


var obj = $.parseJSON('[{"updated": 1348728829383, "username": "buster", "first_name": "Bryson", "last_name": "Arnov", "user_image": ""}, {"updated": 1348728839332, "username": "bill", "first_name": "Bryson", "last_name": "Arnov", "user_image": ""}]');

$('body').html(
'<ul><li>' +

obj.map(function (user) {
return user.username;
}).join('</li><li>') +

'</li></ul>'
);


You first need to format your JSON string according to the standard, which means use strings as
keys. Since you want the JSON to be an array, you want to arrange the data according to the example
above, that is [{ ...}, { ... }, { ... }].

When you output it you cannot use .html() in a loop since it will replace what was there each iteration.
You could use append() to iteratively append to the DOM, but that is slow. Better to construct the whole
HTML string first and insert it into the DOM in one go, as in the example.

As a bonus, the example creates an unordered list of the usernames.

Regarding the timestamps in your JSON (and in the answer), you might consider using ISO Dates.
These are strings in the following format:


"2012-09-27T07:36:45.941Z"


which is also the format that will be used when you convert your objects to JSON to be passed
back to the server:


new Date().toJSON(); // Gives "2012-09-27T07:36:45.941Z"


BR,
Greger.


Lawrence Krubner comments:

For the date, I am using the default timestamp given by the Java "Date" object (that is Java and not Javascript):

(defn add-to-logged-in-registry [this-users-params]
“We assume some user is looking at a site such as wpquestions.com and the Javascript on that site is sending an Ajax request to this app, every 10 seconds, with a map of information about the user, which we need to store in the registry.”
(let [right-now (. (Date.) getTime)
new-user-entry (conj this-users-params { :updated right-now })]
(swap! registry (fn [map-of-user-maps]
(assoc (assoc map-of-user-maps (get new-user-entry “username”) {}) (get new-user-entry “username”) new-user-entry)))))


I wrote this app using the Clojure language but I used several Java libraries in the Clojure code. I posted an early version of the app here:

[[LINK href="http://www.smashcompany.com/technology/who-is-logged-in"]]http://www.smashcompany.com/technology/who-is-logged-in[[/LINK]]

The only thing that I still need to add to the app is the checking of the PHP sessions.

People are deleted from the registry every 15 seconds, therefore it useful to me to work with the timestamp. The goal is to show who is currently logged into sites like this one (Javascript Questions or WP Questions). If your browser has not sent a ping to this URL during the last 15 seconds, we assume you have left the site.