Call external function from ajax() success function - javascript

I have a function defined within $(document).ready() which arranges some JSON into HTML using DoT.js:
$(document).ready(function() {
function arrangeResults(jsonObject, templateFunc) {
$(jsonObject).each(function(i, item) {
$.each(item, function(i2, item2) {
$('#ajax-article-list .col-left').append( templateFunc(item2) );
});
});
};
I have an AJAX call on page load which executes this function to display the data:
$.post(ajaxRequestURL, function(data) {
arrangeResults(ajaxData.pages, projectTemplate);
}
and this works fine.
However I have a set of links which requests more/different JSON data using the click() handler, which should execute arrangeResults again with the returned data, but the function isn't executed:
$('nav.filters a').click(function(ev) {
ev.preventDefault();
$.post(ajaxRequestURL, function(data) {
ajaxData = parseJSON(data);
arrangeResults(ajaxData.pages, projectTemplate);
}
}
This doesn't work. The data is all valid, and everything works if I take the contents of arrangeResults and put them directly within the script, but I was hoping to follow DRY and have an external function that I could call upon both on pageload and when one of the filters is clicked.
I guess it's because the AJAX call is asynchronous but since the function call is within success I presumed this wouldn't cause a problem.

If I understand it right, you have first AJAX call inside $(document).ready() block.
So it could be because you have arrangeResults function inside your $(document).ready() block. Because of that you are unable to call the function from other part of JScript.
Define it like that:
function arrangeResults(jsonObject, templateFunc) {
...
}
$(document).ready(function() {
...
);
and so on.
Correct me if I wrong, please.

Related

Calling function by string not working

I'm trying to write a js function that triggers another, variable, function when complete. I figured I could do this by passing the second function's name as a string, but I can't get it to work. Here's my code:
logMeIn('likeThisPost');
function logMeIn(callBack) {
//First function content
$.post("/ajaxurl/",
{
login_id: login_id,
intent: 'login'
},
function(){
console.log('Logged in, refreshing header');
$.post("/secondajaxurl/",{},
function(data){
//success
if(typeof callBack!=='undefined') {
window[callBack]();
}
}
);
}
);
});
}
This should, according to my thinking, run likeThisPost after successfully completing both ajax calls in logMeIn, but instead I get this error:
window[callBack] is not a function
The function I'm calling on success definitley exists, and besides which, it doesn't look like it's even trying to call that function, but it's treating callBack as literal rather than a string.
I'm using jQuery and have everything wrapped in a $. Where am I going wrong?
With thanks to Jonas W and Rory McCrossan, the answer was to change the passed function to the function name, rather than a string, and then call the function directly rather than using window.
So logMeIn(likeThisPost) instead of logMeIn("likeThisPost") and callBack(); rather than window[callBack]();.
Thanks!

jQuery: Wait for function

I have 2 functions in jQuery and one needs data the other is loading from a DB via php and json(this part works).
My problem is that the first one starts berfore the data is loaded.
How con I fix this?
Here a little code to understand:
function loadBody(){
//Create an calendar of selectet month with classes to Events
}
function loadEvents(){
//loads Events from DB with php and json and puts them into an array
}
I tryed e.g. the following:
function loadCal(){
$.when(loadEvents()).done(loadBody());
}
loadBody not loadBody() : you were executing loadBody instead of giving the callback.
function loadCal(){
$.when(loadEvents()).done(loadBody);
}
$when expects a promise to be returned by the method passed into it. You need to make sure loadEvents method returns a promise.
function loadEvents(){
return $.ajax({
//Make ajax call to loads Events from DB
});
}
function loadBody(){
//Create an calendar of selectet month with classes to Events
}
function loadEvents(){
//loads Events from DB with php and json and puts them into an array
loadBody();//call here after load complete
}
function loadCal(){
loadEvents();
}
the problem is that loadEvents immediatelly returns, so loadBody is called before it finishes to load the file asynchronously. Can you post the full loadCal function? In it you'll have some callback, that saves the data to the array. There you could call loadBody(). I know it's not as nice as you tried, but it should work :)
You can try this:
var loadEvents = function (callback) {
// do stuff...
callback()
};
var loadBody = function () {
loadEvents(function () {
// loadEvents function is already done here...
// continue with loadBody function
})
};

Anonymous function on page load

I'm trying to get better with JavaScript and learn how to utilize my code in functions and keep everything clean. I'm trying to run a function on page-load...
var setColors = function(){
this.init = function(){
$.getJSON('js/colors.json', function(colors) {
$.each(colors, function(i, colors) {
$('<li>', {
text: colors['color'],
'name' : colors['color'],
'data-hex' : colors['hex'],
'data-var' : colors['var']
}).appendTo('#picker');
})
});
}
}
(This is not a color-picker, just a list of colors)
I want setColors() to be executed as soon as the page starts. I read that an anonymous function runs automatically, but this one isn't, I also tried...
$(function(){
setColors();
});
Below the setColors() function and that isn't working ether (The page is just blank). What am I doing wrong and how do I get my function to run on page load? I'm trying to learn so an explanation would be great.
Anonymous functions are not run immediately, you're thinking of Immediately Invoked Function Expressions which happen to often use an anonymous function.
To fix your code:
a) get rid of the this.init function wrapper within the "object" - you're not using it and this.foo only makes sense if you're using new to instantiate an object:
function setColors() {
return $.getJSON(...);
}
Note that returning the $.getJSON() result allows you to register additional deferred object handlers, register error handlers, etc.
b) call the above function in a document.ready handler (which you must do, since the AJAX callback modifies the DOM).
$(setColors);
NB: the latter is a legal way of calling this handler - jQuery will automatically register any function that you pass this way as a document.ready handler. It's similar to writing:
$(function() { setColors() })
but without the extra (useless) function wrapper.
To have that run once the DOM is initialized, you can put it in a ready listener (jQuery):
$(document).on('ready', function() {
setColors();
});
If you want the function to run automatically as soon as it is encountered in the js, after the } that ends the function, add ();
Something like:
function setColors() {
// Code
}();
setColors doesn't return the next function, or call it at the end. YOu could change it to look like:
var setColors = function(){
this.init = function(){
$.getJSON('js/colors.json', function(colors) {
$.each(colors, function(i, colors) {
$('<li>', {
text: colors['color'],
'name' : colors['color'],
'data-hex' : colors['hex'],
'data-var' : colors['var']
}).appendTo('#picker');
})
});
}
init(); // <--- change
}
Which would do the trick for you. You don't even need to "return it" either since the init function itself doesn't return anything, so you could just call it.

How to utilize generic AJAX call with multiple success functions

I am making an ajax call that returns XML. This XML needs to be handled differently based upon the section of the page within the site the user is on. Thus, I would like to implement 1 ajax function that makes the calls, and has a variable success function... I'm sure it is simple but I've searched for a while and cannot figure it out..
function makeAjaxCall(variableSuccessFunction) {
$.ajax.... (ajax stuff goes here)...
success: variableSuccessFunction(xml)
}
function ViewOne(xml) {
//take the XML and update the dom as appropriate
}
function ViewTwo(xml) {
//take the XML and update the dom as appropriate
}
$(document).ready(function() {
//be able to call either one of these functions
makeAjaxCall(ViewOne);
makeAjaxCall(ViewTwo);
}
You've basically got it! Just one tweak:
function makeAjaxCall(variableSuccessFunction) {
$.ajax.... (ajax stuff goes here)...
success: variableSuccessFunction // no (xml)
}
You're passing around function references. success is passed a reference to variableSuccessFunction (whatever that may be) and will call it just like it would if you had supplied an anonymous function to it. No need to invoke it inside of makeAjaxCall.

Pass a javascript function through JQuery $.post

Basically what I am trying to do is pass a callback function through PHP using JQuery $.post. Something like:
function loadPage()
{
$.post('myurl.php', { 'callbackfunc' : function (info) { alert(info); } },
function(data) {
$("#divid").html(data);
} );
}
Where myurl.php creates a page with a table. The table rows have an onclick handler that calls the callback function.
The problem is, passing the function this way sends it as undefined via post, and if I enclose it in quotes, then when I try to call it I get the error that it is not a function.
Is there any way to do what I am describing?
there is a way but not normally recommended. You can pass the function as a string and then when you receive the function with javascript use the eval() function.
function loadPage()
{
$.post('myurl.php', { 'callbackfunc' : "function (info) { alert(info); }" },
function(data) {
$("#divid").html(eval(data));
} );
}
pass it as a string (function body in double quotes, probably using escape characters).
You could attach your function to your table rows after the table has been returned, rather than try to have the php code create it with the proper callback.
function loadPage(callbackfunc)
{
$.post('myurl.php', {},
function(data) {
$("#divid").html(data);
$("#divid").find("tr").each($(this).click(callbackfunc));
} );
}
there is no way to do what you are describing, but there is a probably way to do what you want. ( i dont know what you want )
you cant pass a JS function to the server. you can only pass strings.
edit:
based on your response, i can tell you that your way of doing this is not only not good, but dangerous, as it allows XSS.
it would be better to delegate the click function to the div where you are inserting the table like this:
function loadPage(){
$("#divid").delegate('tr', 'click', function(evt){
//this code is different per page, change color, alert, etc
});
//after the above event is delegated, you can reload the table as much as you want, without needing to rebind the above event
$.post('myurl.php', function(data) {
$("#divid").html(data);
});
}

Categories

Resources