Supply a non-anonymous function to Jquery: success + additional confusion - javascript

I can not get my JQUERY .ajax request to accept a function (non-anonymous) to the success condition.
The reason why I am choosing to not use an anonymous function (which I know will work) is because I think they are more difficult to debug and read. I also read that functions should be broken out as a good design and code-reuse factor.
$.ajax({
url: total_url,
type: "POST",
data: {already_voted: already_seen},
success: ajax_get_data_success(data),
error: function (XMLHttpRequest, textStatus, errorThrown) {
console.log('XHR ERROR ' + XMLHttpRequest.status);
}
My success function is NEVER sent the DATA object?
My error is Uncaught ReferenceError: data is not defined
Obviously data has not been defined, it is supposed to accept the DATA upon success.
Here is my function for the success case:
function ajax_get_data_success(data)
{
try{
console.log(data.id);
console.log("Recieved" + data.id);
update_seen_state(data.id);
update_ui();
}catch(err)
{
console.log("Ajax_get_data", err);
}
}
** Update: As suggested I removed the extra paramaters and the call worked. However, this has sent me through the rabbit hole further as to how calls are made in JQUERY.
**Per the JQUERY API, the success case takes only 3 paramater, and the error case takes 3 paramaters. From a programatic standpoint, that means when a successful ajax connection has been made, their code will pass to MY FUNCTION only 3 paramaters.
Wouldn't Javascript get confused if I increased the number of parameters that were allowed to be passed to the function?

The error is self explanatory. You are using the variable data which is not defined above. The javascript engine don't know what data is !
In your case for your ajax success event handler, just specify your function name, no need to specify the param there. Just have it in your function definition (which you already have).
This should work.
success: ajax_get_data_success,
EDIT : As per the comment
What if I wanted to pass it additional arguments?
You can do this
var myArray = ["My","Custom","Array","I want to pass"];
$.ajax({
url: total_url,
type: "POST",
data: {already_voted: already_seen},
success:function (ajaxResponse) { ajax_get_data_success(myArray , ajaxResponse) }
});
and now your method accepts 2 params
function ajax_get_data_success(yourData,ajaxResponseData)
{
console.log(yourData);
console.log(ajaxResponseData);
}
Well, now you are using again an an anonymous method in your success event.

Related

What's the difference between calling a javascript function with arguments, and without

I was trying to get data back from an ajax call, and was using the code
jQuery.ajax({
type: 'POST',
url: '/chatlog',
success: exoticlangAjaxCompleted,
data:'messageLog=' + privateMessageLogJson,
dataType: 'json'
});
The data was in a JSON array (key = "messageLog")
Why did it work to call
success: exoticlangAjaxCompleted,
but not
success: exoticlangAjaxCompleted(),
or
success: exoticlangAjaxCompleted(messageLog) ??
JS function is:
function exoticlangAjaxCompleted(messageLog){
console.log('exoticlangAjaxCompleted!');
console.log('chat log is: ' + messageLog);
console.log('chat log is: ' + dump(messageLog));
}
The success argument expects a reference to function that will be invoked when the AJAX request is complete.
With the following:
success: exoticlangAjaxCompleted,
You are passing a reference to a function as required.
Whereas in this instance:
success: exoticlangAjaxCompleted(),
You are invoking your exoticlangAjaxCompleted function and passing the result to the success argument. Unless your function returns a function, this will not work!
The reason the former syntaxes work is because success expects a function object (in order to call it with arguments, if it wanted to), where just calling a function doesn't return a function object. When you call a function with the function() form, it produces an output (even if that output is undefined) This is also why this form works:
...
success: function() {
// Some callback code
}
...
So, how are they different? To show how, let's look at the WebKit console:
As you can see, executing myFunc returns the function itself, whereas myFunc() returns **an object that would be useless to select:*
My understanding is that you can't pass arguments this way.
If you try doing this:
success: function(){exoticlangAjaxCompleted(messageLog);},
Then that might work.
From the Jquery documentations, here is a section about the success callback:
"A function to be called if the request succeeds. The function gets
passed three arguments: The data returned from the server, formatted
according to the dataType parameter; a string describing the status;
and the jqXHR (in jQuery 1.4.x, XMLHttpRequest) object."
jQuery.ajax()
So you have to make a trick, like here: Pattern of additional parameters
success: function(..){
...
}

maintain value of variable outside function in javascript?

I try to manipulate a variable inside a function. But it seems to forget the values once I exit the function, eventhough the variable is declared outside the function.
The essential code:
var posts = {};
// Perform a data request
// skjutsgruppens-page
$.oajax({
url: "https://graph.facebook.com/197214710347172/feed?limit=500",
*SNIP*
success: function(data) {
$.extend(posts, data);
}
});
// Gruppen
$.oajax({
url: "https://graph.facebook.com/2388163605/feed?limit=500",
*snip*
success: function(data) {
$.extend(posts, data);
}
});
The oajax retrievies data from facebook. I want to make a variable that contains the data from both oajax methods.
The actual code: http://eco.nolgren.se/demo/resihop/#
The issue is likely that the success function executes at an arbitrary time in the future--unless you specifically access posts after you know the success function has executed, you will receive undefined results, completely dependent on function and access timing.
The best approach is to handle this correctly by doing necessary work inside in the success function, or use something like jQuery's .when function.

Using Javascript / JQuery to access an array built from an external XML file

I hope this is not too much of a newbe question but I've been pulling my hair out for a while now so thought I'd give in and ask for my first piece of advice on here.
I'm trying to read an external xml file using javascript / jQuery / ajax and place the retrieved data into an array so that I can then reference it later.
So far I seem to be doing everything right upto the point I put the data into the array but then I'm struggling to to read the data anywhere other than inside the function where I create it. Why am I not able to access the Array from anywhere other than in that function?
Here is my code...
Please help!!
$.ajax({
type: "GET",
url: "data.xml",
dataType: "xml",
success: do_xmlParser
});
function do_xmlParser(xml)
{
var myArray = new Array();
$(xml).find("tag").each(function ()
{
myArray.push($(this).find("innerTag").text());
});
console.log("inside "+myArray); // This outputs the array I am expecting
return myArray; // is this right???
}
console.log("outside: "+myArray); // This does NOT output the array but instead I get "myArray is not defined"
You're defining do_xmlParser as a callback to an asynchronous function (success of the jquery ajax call). Anything you want to happen after the ajax call succeeds has to occur within that callback function, or you have to chain functions from the success callback.
The way you have it now, the actual execution of code will go:
ajax -> file being requested -> console.log ->
file transfer done -> success handler
If you're doing some critical stuff and you want the call be to synchronous, you can supply the
async : false
setting to the ajax call. Then, you should be able to do something like this:
var myArray = [],
do_xmlParser = function (xml)
{
$(xml).find("tag").each(function ()
{
myArray.push($(this).find("innerTag").text());
});
};
$.ajax({
type: "GET",
url: "data.xml",
dataType: "xml",
success: do_xmlParser,
async: false
});
console.log("outside: " + myArray);
The async option doesn't work for cross-domain requests, though.
NOTE
I don't recommend doing this. AJAX calls are supposed to be asynchronous, and I always use the success callback to perform all of the processing on the returned data.
Edit:
Also, if you're into reading... I'd recommend jQuery Pocket Reference and JavaScript: The Definitive Guide (both by David Flanagan).
look close and you will see. You are actually firing up an array that dosen't exist. You have declared myArray inside function. Try do something like this.
console.lod("outside :"+do_xmlParser(xml)); // I think that when you merge a string and an array it will output only string, but I can be wrong.

Scoping Out the Javascript Function Scope Problem

It's very clear I don't understand how functions are scoped in Javascript. Here's the latest example:
function riseData() {
var jsonResult;
$.ajax({
success: function(data, textStatus, jqXHR){
jsonResult = jqXHR.responseText;
alert("Inside: " + jsonResult);
},
error: function (jqXHR, textStatus, errorThrown) {
$('#errLog').append('<br>Status: ' + qXHR.statusText);
}
});
return jsonResult;
}
$(document).ready(function(){
var intervalID = setInterval('UTCclock()',100);
alert("Outside: " + riseData());
});
When I execute this, the "Inside" alert functions properly, but the "Outside" alert displays "undefined", even though riseData() is obviously defined only a few lines earlier. There is a $.ajaxSetup earlier in the code which defines the parameters for the ajax call. The ajax call successfully returns the requested data in the "Inside" alert.
I just haven't the slightest clue how to make the necessary data (jqXHR.responseText) available to other parts of the script.
Can anyone point me at a "Javascript Scoping for Dummies" how-to that addresses this issue?
Your example is scoped just fine. Your problem is you don't understand the implications of how JavaScript is mainly asynchronous.
Let me go through your example to show you.
Your document ready handler runs.
It calls riseData.
riseData declares a variable, jsonResult.
riseData calls $.ajax, which schedules an AJAX request to be done, but the response will happen later.
Since $.ajax is usually non-blocking/asynchronous, riseData continues and returns jsonResult. Since jsonResult has not been assigned yet because the AJAX request has not completed, the default value of undefined is returned.
In the document ready handler, you end up with alert("Outside: "+undefined);.
An event loop to a few milliseconds later, this happens:
The AJAX request is completed. jQuery forwards this on to your callback.
jsonResult is set, but riseData has already returned.
The alert inside riseData alerts with the new data, after the document ready handler has already alerted undefined.
There are two solutions to this problem. The first solution is simple, but often results in a worse user experience. This solution is to add the async: false option to $.ajax. This makes $.ajax block and freeze the browser.
The second solution is to adopt an asynchronous style for almost everything. That means making riseData accept a callback and calling it inside the AJAX response handler. Here's your code transformed with this method:
function riseData(callback) {
$.ajax({
success: function(data, textStatus, jqXHR){
var jsonResult = jqXHR.responseText;
alert("Inside: " + jsonResult);
callback(jsonResult);
},
error: function (jqXHR, textStatus, errorThrown) {
$('#errLog').append('<br>Status: ' + qXHR.statusText);
}
});
}
$(document).ready(function(){
//var intervalID = setInterval('UTCclock()',100);
// Unrelated, but it's better to pass a
// function into setInterval than a string.
var intervalID = setInterval(UTCclock, 100);
riseData(function(jsonResult) {
alert("Outside: " + jsonResult);
});
});
This is only partially a scope issue. Your ajax call is asynchronous, so the riseData() function returns a value before the ajax call is executed. Try setting your variable outside the method.
var jsonResult;
function riseData() {
$.ajax({
...
jsonResult should not only be available in riseData(), but also out. However, you'll still have the issue of exactly when it gets populated.
A link for a little more explanation:
What is the scope of variables in JavaScript?

jQuery $.post - how to call a callback function if $.post fails and or if the response is not the type you expect

Here's the thing, I have a jquery click event handler, that calls a post on click.
The type that it expects (4th parameter of $.post()) is "json". However, on the
server side; there are two responses to the post: it's either json or html response. The problem is, if it returns html, the callback function isn't called (because the $.post expects a json?).
How can I react to this? I want something that if the server side script returns a json, execute callback, otherwise do another. Is that possible? Can I check the response type with $.post?
You'll most likely want to use the generic jquery.ajax function. In particular the dataType: 'text' property should allow you to parse your return value in whatever method works for you. You can also use the parseJSON function
$.ajax({
url: 'url',
type: 'post'
dataType: 'text',
success: function(text) {
if (json) {
var obj = $.parseJSON(text);
} else {
var html = $(text);
}
}
});

Categories

Resources