Getting json on Ajax response callback
Solution 1
This is the correct syntax for retrieving JSON with Prototype
onSuccess: function(response){
var json = response.responseText.evalJSON();
}
Solution 2
There is a property of Response: Response.responseJSON which is filled with a JSON objects only if the backend returns Content-Type: application/json, i.e. if you do something like this in your backend code:
$this->output->set_content_type('application/json');
$this->output->set_output(json_encode($answer));
//this is within a Codeigniter controller
in this case Response.responseJSON != undefined which you can check on the receiving end, in your onSuccess(t) handler:
onSuccess:function(t) {
if (t.responseJSON != undefined)
{
// backend sent some JSON content (maybe with error messages?)
}
else
{
// backend sent some text/html, let's say content for my target DIV
}
}
I am not really answering the question about the second parameter of the handler, but if it does exist, for sure Prototype will only provide it in case of proper content type of the response.
Solution 3
This comes from Prototype official :
Evaluating a JavaScript response Sometimes the application is designed to send JavaScript code as a response. If the content type of the response matches the MIME type of JavaScript then this is true and Prototype will automatically eval() returned code. You don't need to handle the response explicitly if you don't need to.
Alternatively, if the response holds a X-JSON header, its content will be parsed, saved as an object and sent to the callbacks as the second argument:
new Ajax.Request('/some_url', { method:'get', onSuccess: function(transport, json){
alert(json ? Object.inspect(json) : "no JSON object"); }
});
Use this functionality when you want to fetch non-trivial data with Ajax but want to avoid the overhead of parsing XML responses. JSON is much faster (and lighter) than XML.
Solution 4
You could also just skip the framework. Here's a cross-browser compatible way to do ajax, used in a comments widget:
//fetches comments from the server CommentWidget.prototype.getComments = function() { var commentURL = this.getCommentsURL + this.obj.type + '/' + this.obj.id; this.asyncRequest('GET', commentURL, null); } //initiates an XHR request CommentWidget.prototype.asyncRequest = function(method, uri, form) { var o = createXhrObject() if(!o) { return null; } o.open(method, uri, true); o.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); var self = this; o.onreadystatechange = function () {self.callback(o)}; if (form) { o.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); o.send(makePostData(form)); } else { o.send(''); } } //after a comment is posted, this rewrites the comments on the page CommentWidget.prototype.callback = function(o) { if (o.readyState != 4) { return } //turns the JSON string into a JavaScript object. var response_obj = eval('(' + o.responseText + ')'); this.comments = response_obj.comments; this.refresh() }
I open-sourced this code here http://www.trailbehind.com/comment_widget
Comments
-
AntonioCS almost 2 years
I am trying to create a little ajax chat system (just for the heck of it) and I am using prototype.js to handle the ajax part.
One thing I have read in the help is that if you return json data, the callback function will fill that json data in the second parameter.
So in my php file that gets called I have:
header('Content-type: application/json'); if (($response = $acs_ajch_sql->postmsg($acs_ajch_msg,$acs_ajch_username,$acs_ajch_channel,$acs_ajch_ts_client)) === true) echo json_encode(array('lastid' => $acs_ajch_sql->msgid)); else echo json_encode(array('error' => $response));
On the ajax request I have:
onSuccess: function (response,json) { alert(response.responseText); alert(json); }
The alert of the response.responseText gives me {"lastid": 8 } but the json gives me null.
Anyone know how I can make this work?
-
AntonioCS about 15 yearsThanks! But I did read somewhere about that second parameter thing :P
-
umpirsky over 13 yearsThanks Jose. Yeah, prototypejs.org/learn/introduction-to-ajax it says that second param is json, crap, wont work for me - onSuccess: function(transport, json){ alert(json ? Object.inspect(json) : "no JSON object"); }