Problems with jQuery ajax function - javascript

I'm having a trouble since jQuery.ajax, in this particular case, doesn't seem to happen, so that the function always return NaN undefined as result:
function requestUploadedSearch()
{
var cookie = JSON.parse(readCookie("user_search_cookie"));
$.ajax({
dataType: "script",
async: false,
data: {
context: "search-get",
code: removeNull(cookie, cookie !== null, "code")
},
success: function(data)
{
return search_return["keywords"];
}
});
delete cookie;
}
I've also tried to write something like
success: function() { return "<nothing happens>"; }
But what I receive is undefined.
Please answer, I'm really freaking out with that.
Thanks in advance.

What you're trying to do is fundamentally impossible. Your ajax operation is asynchronous (no it isn't durrr).
Instead, re-architect your API:
function requestUploadedSearch( callback )
{
var cookie = JSON.parse(readCookie("user_search_cookie"));
$.ajax({
dataType: "script",
async: false,
data: {
context: "search-get",
code: removeNull(cookie, cookie !== null, "code")
},
success: function(data)
{
callback( search_return["keywords"] );
}
});
delete cookie;
}
Then, when you invoke it, instead of expecting a return value, pass in a function to respond to the returned data:
requestUploadedSearch( function( value ) {
// ... do stuff with "value" ...
});
edit — Doh! #nickd is correct; since you're making the call synchronously (which you really should seriously consider not doing; it's pretty bad for your user experience) the story is different. Still, however, the approach above would work.

Pointy is pointing (hah) you in the more usual way of doing things. However as you have async: false set, your success: function is never called. Putting
return search_return["keywords"];
after the delete cookie line will return as you have it in your example, but you aren't using the result of the ajax call anywhere I can see, so I'm not sure that there's any point.

Related

jQuery ajax returned data: json and html mix?

I have this ajax request to get the data from my server, and the dataType is always html by default. But sometimes it would return json from the server, so I want to check if the returned data is html then execute A else execute B. Is it possible?
My jquery,
$.ajax({
type: "GET",
dataType: "html",
url: request_url,
context: $('#meat'),
async: true,
beforeSend: function () {},
success: function (returndata, status, jqXHR) {
if ($.parseJSON(returndata) === false) A;
else B.
}
});
I get this error when the returned data is html,
SyntaxError: JSON.parse: unexpected character
So how can I make this code versatile?
I'm not sure if there is a better way, but you could try... catch
$.ajax({
type: "GET",
url: request_url,
context: $('#meat'),
async: true,
beforeSend: function() {
},
success: function (returndata, status, jqXHR) {
var parsed;
try
{
parsed = $.parseJSON(returndata);
// Execute B
}
catch(e)
{
// treat as html then
// do parsing here
parsed = returnData;
// Execute A
}
}
});
Essentially, your code is just plain wrong - your serverside API is violating all principles of predictability if the return type can vary in an inconsistent manner. Your code should never have to guess at the type of the returned data.
Having said that, a simple try/catch will help as a workaround for the erratic behaviour if you don't want to fix it. Ie.
try {
if ($.parseJSON(returndata) === false) A;
} catch(e) {
// Treat as HTML here.
}
It's not pretty, but that's what you get for having an unpredictable API that isn't pretty to begin with.
may be you need to handle it like this
try{
var response=jQuery.parseJSON('response from server');
if(typeof response =='object')
{
//control would reach this point if the data is returned as json
}
else
{
//control would reach this point if data is plain text
if(response ===false)
{
//the response was a string "false", parseJSON will convert it to boolean false
}
else
{
//the response was something else
}
}
}
catch(exp){
//controls reaches here, if the data is html
}
Since you need to check the html data as well, you may need to take care of this,
Might also need to use a try / catch for exceptions if it is possible that parseJSON is going to be dealing with something other than JSON values (i.e. HTML)
REF:How can I check if a value is a json object?
EDIT:Edited to make code more precise towards solution

Performing a synchronous Ajax request from jQuery?

I know it sounds like something that's been asked before, but for all my hunting, I can't find anything matching what I'm looking for.
I'm working on a project that's rather heavily based on Ajax. I'm using jQuery, but even with its beautifully streamlined code, it's still messy when I've got it to the point that the code is exactly the same, except for one single command passed through the data field.
So I tried setting it up inside a handler function, like so:
function _call(task, opts, async) {
if(typeof async !== "boolean") { async = true; }
opts = $.extend({}, opts, options);
$.ajax({
url: "myphpfile.php",
dataType:"JSON",
type:"POST",
async:async,
data: { task: task, opts: opts }
}).done(function(data) { return data; });
}
For those who read through, you'll notice that there's a var,
options, that hasn't been defined in the example. It has actually
been assigned, it's just been omitted for clarity purposes.
I came to realize that this doesn't work, as even when it's set to async: false, the code still continues after the call of _call(...), therefore not getting the results in time. I've tried a few different variations, including passing an anonymous function to the handler and then using that as the .done() function, but it wouldn't interact with outside variables, defeating the purpose.
All I'm looking for is a system that will let me use it something like this:
var returnedData = _call("thisismytask");
var returnedDataWithOptions = _call("thisisanothertask", {'option': 'option1'});
I really hope this is possible. I'm sure it would be, as the main purpose of functions is to remove the need for unnecessarily repeated code.
Thanks. :)
You could do this:
function _call(task, opts) {
opts = $.extend({}, opts, options);
return $.ajax({
url: "myphpfile.php",
dataType:"JSON",
type:"POST",
data: { task: task, opts: opts }
});
}
It removes the need for passing a callback into _call, but functions just the same.
_call("thisisanothertask", {'option': 'option1'}).then(function(data) {
// function body here
});
you are probably best doing this
function _call(task, opts, callback) {
opts = $.extend({}, opts, options);
$.ajax({
url: "myphpfile.php",
dataType:"JSON",
type:"POST",
data: { task: task, opts: opts }
}).done(function(data) { callback(data); });
}
use like this
_call("thisisanothertask", {'option': 'option1'}, function(data) {
//do things with data
});
You cant really do this, as _call cant return straight away as it may take a while to get a response and even if you could it could lock your browser which is not good.
var returnedData = _call("thisismytask");
var returnedDataWithOptions = _call("thisisanothertask", {'option': 'option1'});
you need to use it like this:
_call("thisismytask", null, function(returnedData) {
//use returnData
});
_call("thisisanothertask", {'option': 'option1'}, function(returnedDataWithOptions) {
//use returnedDataWithOptions
});
If you needed the result of thisismytask before thisisanothertask you would have to do:
_call("thisismytask", null, function(returnedData) {
_call("thisisanothertask", {'option': 'option1'}, function(returnedDataWithOptions) {
//use returnData
//use returnedDataWithOptions
});
});
You should be using callbacks. You also shouldn't be using async: false as this will block the UI thread in browser. You can use jQuery.when() to sync your various tasks. First change your method like this:
function _call(task, opts) {
opts = $.extend({}, opts, options);
return $.ajax({
url: "myphpfile.php",
dataType:"JSON",
type:"POST",
data: { task: task, opts: opts }
});
}
Now you can call it like this:
$.when(
_call("thisismytask"),
_call("thisisanothertask", {'option': 'option1'})
).done(function(firstCallResults, secondCallResults) {
//*CallResults is an array with the following structure: [data, statusText, jqXHR]
var returnedData = firstCallResults[0];
var returnedDataWithOptions = secondCallResults[0];
...
});
This way you keep all the benefits of AJAX asynchrounous nature (those tasks will run in parallel unless server doesn't support it) and get your results back together when they are all available.
I found a solution. #Slavo pointed it out to me.
https://stackoverflow.com/a/6685294/563460
As you're making a synchronous request, that should be
function getRemote() {
return $.ajax({
type: "GET",
url: remote_url,
async: false,
}).responseText; }
Example - http://api.jquery.com/jQuery.ajax/#example-3
Now I just have to decode from text to proper JSON. Thank you everyone. :)
Use jQuery's syntax -
its worked for me,
$.ajaxSetup({async: false});

jQuery ajax success callback function - how to make it anonymous?

I am unable to get the success callback to work in a jQuery ajax call. The following code calls interpretResponse() just fine, but of course resultJSON is undefined:
var that = this;
jQuery('#fsForm1492441').submit(function(event) {
event.preventDefault();
jQuery.ajax({ type: "POST",
url: "format_result.php",
data: jQuery(this).serialize(),
success: that.interpretResponse(),
dataType: "json"
});
});
function interpretResponse(resultJSON) {
// code here to handle resultJSON
}
I want something like:
success: function(resultJSON) {
that.interpretResponse(resultJSON);
},
How should the success callback be written?
just do this :
success: interpretResponse,
your code will look like this -
var that = this;
jQuery('#fsForm1492441').submit(function (event) {
event.preventDefault();
jQuery.ajax({
type: "POST",
url: "format_result.php",
data: jQuery(this).serialize(),
success: interpretResponse,
dataType: "json"
});
});
function interpretResponse(resultJSON) {
// code here to handle resultJSON
}
The answer above was correct, but it turned out that I was dealing with a different problem. The weird bug in FireFox that keeps ajax calls from getting past readyState 1 was causing the callback function to not load. I ended up using the workaround described here:
Ajax won't get past readyState 1, why?
Basically getting Firefox to set the callback onload rather than onreadystatechange.
Thanks to pXL for the answer to the question the way I asked it.

jQuery ajax function return

I have this function that embeds flash :
function embedswfile(target, swf, base, width, height) {//dosomething}
And I want to call the function like this
embedSwf("flashgame",decode("<?=base64_encode($path['location'])?>"),decode("<?=base64_encode($path['base_directory'])?>"),"800","600" )
The idea is that whenever someone looks for any swf inside my website,he wont find anything clean.I will change the encoding algorithm,but this is just temporary. In order for that function to work,whenever I call the function 'decode' it must return a single value. PHP contains
<?php
echo base64_decode($_POST['s']);
?>
I tried this but it still wont work
var globvar;
function processdata(newmsg) {
globvar = newmsg;
}
function decode(s){
$.ajax({type: "POST",
url: "includes/decode.inc.php",
data: "s=" + s,
success:function(newmsg){
processdata(newmsg);
}
});
return globvar;
}
Important:
Forget about using Ajax and encoding, decoding the path. What do you think you gain from it? Security? No. One can figure out that this is bas64 encoded or he just monitors the network traffic and reads the response from the Ajax call.
Just do
embedSwf("flashgame","<? =$path['location']?>"),"<?=$path['base_directory']?>","800","600" )
Really, you cannot prevent someone else seeing the data and are just making things more complicated for you.
(Or you have to decrypt the data with JavaScript.)
(original answer is still correct nevertheless)
Ajax is asynchronous so something like var test = decode(s); will never work. The decode function will return before the Ajax call finishes.
Instead, put your logic into the callback handler. For example, if your code was this before:
var retdata = decode('s');
// here comes code that handles retdata
put the code into a function and call it from the success handler:
function process(retdata) {
// here comes code that handles retdata
}
function decode(s){
$.ajax({type: "POST",
url: "includes/decode.inc.php",
data: "s=" + s,
success:function(newmsg){
process(newmsg);
}
});
}
This seems to be a very common problem to all beginners. You will find a lot of questions here that deal with the same problem.
Update:
It is not nice, but you could change the function to
function decode(s, cb){
$.ajax({type: "POST",
url: "includes/decode.inc.php",
data: "s=" + s,
success:function(data){
cb(data);
}
});
}
and do
decode("<?=base64_encode($path['location'])?>", function(location) {
decode("<?=base64_encode($path['base_directory'])?>", function(dir) {
embedSwf("flashgame",location,dir,"800","600" );
});
});
Update 2:
For completeness, you can make the Ajax call synchronous, by using async: false. Then this will work:
function decode(s){
var ret;
$.ajax({type: "POST",
url: "includes/decode.inc.php",
data: "s=" + s,
async: false,
success:function(newmsg){
ret = newmsg;
}
});
return sync;
}
var val = decode(s);
However, this will block the browser until the Ajax call finished. You have to test whether this matters in your case or not.
Update 3:
You could also change your PHP script to not only accept one parameter but several and process both strings in one go.

Modifying jQuery $.ajax() success method during request

In the web app I am working on there is potential for very long running ajax queries.
I'm using jQuery's $.ajax method to do something like:
this._xhr = jQuery.ajax({
type: "GET",
url: "/path/to/service",
data: "name=value",
success: function(data, message){
// handle a success
},
dataType: "json"
});
Is there a way to modify the success callback after this._xhr.readyState = 2 (loaded) and before this._xhr.readyState = 4 (completed)
I tried modifying this._xhr.onreadystatechange but found that jQuery does not define onreadystatechange.
The abort method sounds like the best option to me.
I don't know much about the ajax method internals, but I can think of a few ways to do what you want. Both involve global state and would break if it's possible for your user to send a second request before the first has finished, so I'm not sure I recommend them.
First, you could keep a reference to the method that does your success work, and change it:
MySuccessMethod = function(d, m) { /* handle a success */ };
this._xhr = jQuery.ajax({
type: "GET",
url: "/path/to/service",
data: "name=value",
success: function(data, message){ MySuccessMethod(data, message); },
dataType: "json"
});
// later...
// user cancels request, so change the success method
MySuccessMethod = function(d, m) { /*print a simple message*/ }
Alternatively, you could just put all the logic in the one success method, and use a global flag to determine what to do:
success: function(data, message){
if (RequestHasBeenCancelled) {
//display a simple message
}
else {
// handle a success
}
},

Categories