How to create global variable in query and usable with javascript - javascript

$(document).ready(function ()
{
$.ajax(
{
url: "Bibliotheek.xml",
dataType: "xml",
success: function (data)
{
var song = $(data).find('key').filter(function ()
{
return $(this).text().indexOf('Name') != -1;
}).each(function()
{
window['globalVar']= $(this).next('string').text();
console.log(globalVar);
});
}
});
});
I want to use globalVar outside that each loop. But once i put de console.log outside the function. It tells my globalVar is undefined.Is it also possible to use that variable later on in javascript code?

This probably happens, because you loop over an empty list (i.e. it never enters the .each callback). This thing is wrong: .find('key'). It searches for a key tag (which is not HTML, unless you actually are not dealing with HTML?). Perhaps you were looking for .find('.key')?
EDIT: It seems that you want to put console.log outside of ajax call. If you do, then you're out of luck, since you are trying to log a variable that does not exist yet. That's because a in ajax stands for asynchronous, i.e. the piece of code will run later.
EDIT 2: Welcome to asynchronous programming! It seems that you are trying to force ajax to be synchronous, which is wrong and pure eveil. Don't do it. You're code should be similar to this:
var my_fn = function(clb) { // <-- this is callback to be called later
var els = [];
$.ajax({
url: "Bibliotheek.xml",
dataType: "xml",
success: function (data) {
var song = $(data).find('key').filter(function () {
return $(this).text().indexOf('Name') != -1;
}).each(function() {
var el = $(this).next('string').text();
els.push(el);
});
clb(els); // <-- call it now
}
});
};
$(document).ready(function() {
my_fn(function(els) {
console.log(els);
// do coding here
});
});

Define the globalVar outside of the functions...
var globalVar;
var song = {...
console.log(globalVar);//will work here
};
console.log(globalVar);//and, will work here

Related

How can we make a JavaScript property global?

Please refer the below example code
var report = {
chartTypes : null,
init: function () {
this.getChartTypes(function(data){
this.chartTypes = data;
});
},
getChartTypes: function(callback) {
$.ajax({
data:'',
url:'',
success:function(response){
chartTypes = JSON.parse(response);
callback(chartTypes);
}
});
},
getToolbar:function() {
this.chartTypes --------------- NULL
}
}
getChartTypes function load different chart types via AJAX. Therefore i put it as a callback function. Data is received successfully. But when i use this.chartTypes in a different function like getToolbar it says this.chartTypes is null. Even i have initialized the same in the starting. May be scope issue. Please advise.
You are assigning to a variable (probably global) called chartTypes, but that isn't the same as reoprt.chartTypes. You need to assign to this.chartTypes, but this in your anonymous function won't be the same as this outside it, so you need to remember that value using another variable:
getChartTypes: function(callback) {
var self = this;
$.ajax({
data:'',
url:'',
success:function(response){
callback( self.chartTypes = JSON.parse(response) );
}
});
}
With an OOP approach, most developers would use a method and use .bind() to maintain the proper scope when the asynchronous success method is triggered. This way you do not have to worry about closures and using variables to hold the scope of this.
var report = {
chartTypes : null,
init: function () {
this.getChartTypes();
},
getChartTypes : function(callback) {
$.ajax({
data:'',
url:''
}).done(this._setSuccessResponse.bind(this));
},
_setSuccessResponse : function(data){
this.chartTypes = data;
},
getToolbar : function() {
console.log(this.chartTypes);
}
}
You also need to make sure that when you call getToolbar that the Ajax call has also been completed.

how to pass function in json as a function?

in arrayRec , onShow value should be a function.
Following is my reference code.
Any help?
This is my reference code:
if (rec.element_flag == '111'){
var arrayRec = [];
$.ajax({
type:'GET',
url: "/aps/one-url",
success: function(responseData){
for (var i = 0; i < responseData.length; i++){
var recJ;
var newFunction1 = function onshowdata(counter){
if(responseData[counter].fields.on_show_fn != null){
return function responseData[counter].fields.on_show_fn;
}
else
return;
}
recJ = {
element: responseData[i].fields.element_class,
placement: responseData[i].fields.placement,
title: responseData[i].fields.title,
content: responseData[i].fields.content,
onShow: newFunction1(i)
}
arrayRec.push(recJ);
console.log('-------arrayRec------');
console.log(arrayRec)
aps.walk.setupBootstrap(arrayRec);
}
},
error: function(){
alert('get failure');
}
});
}
Tried many ways but what I am missing?
in JSON, only text can be used, not objects. Functions are objects too. So, in JSON, name of the function can be passed, not the function object. An alternate way is to send the text of that entire function, which can be run using "eval", though this way is not recommended.
Use closure technique here. Define function above the ajax code, and use the name of the function inside it, which is a standard method of doing this.

How can I pass this specific variable I'm using jquery-ajax

I want to pass the "passedThisValue" to my "start_battle" function and use the "start_battle" function in my "Rematch". But the modal just hangs why is this happening? what could be wrong? Please help! :) Thank you.
CODE:
function start_battle(){
$.ajax({
data: {
receivePassedValue: passedThisValue
},
success: function(data){
}
});
}
$("#start_battle").click(function() {
$.ajax({
success: function(data){
var toAppend = '';
if(typeof data === "object"){
var passedThisValue = '';
for(var i=0;i<data.length;i++){
passedThisValue = data[i]['thisValue'];
}
start_battle(); // can I still get the passedThisValue?
}
}
});
$("#battle").dialog({
modal:true,
buttons: {
"Rematch": function(){
start_battle(); // can I still get the passedThisValue?
}
}
});
$("#battle").show(500);
});
When you call a function, you don't use function start_battle();, you just use start_battle();.
When you pass a value to a function, you need to use this syntax: start_battle(param1, param2);.
When you want to get a value from a function, you need to return it in the function, like so:
function start_battle(param1) {
// Do something
return param1;
}
When you want to store a returned value from a function, you do something like: var returned = start_battle(param1);
And the fact that you don't know why the modal just hangs, means that you didn't check the browser's error console, which can hold some pretty important information on what's wrong. Try checking that and posting here so we can see the current problem
Your function declaration seems a little off. I think you should leave off the $ from function. Just do this
function start_battle() {
Also, when you're calling a function, you don't say function before it. And if you want to pass a value to the function, you have to put it inside the parenthesis, both when defining the function and when calling it. Like this
function start_battle(someValue) {
// do some stuff with someValue
}
// inside your .click, call start_battle like this
start_battle(passedThisValue);
Pretty basic stuff. But either one of those problems could be causing the hang, which was likely a javascript error.

JQuery/JavaScript : refactoring nested functions

I have this interesting jQuery function. It basically adds a click handler to link, and when that is clicked, it will load a form to allow the user to edit the content. and the form is submitted by AJAX, and will display a success message when it's done.
The outline is below; needless to say, this is messy. I could have each of the callback as a class method. What other ways are there to refactor nested functions? I am also interested to see if there are ways that variables declare in a parent function still retain its value down to the nested function after refactoring
$('a.edit').click( function() {
// ..snipped..
// get form
$.ajax({
success: function() {
// add form
// submit handler for form
$(new_form).submit(function() {
// submit via ajax
$.ajax({
success: function(data) {
// display message
}
})
})
}}
)
}
I guess the interesting part of your question is how to refactor without loosing access to the closure variables. Here is my suggestion:
Version one: nested, with closures and variable access:
var a;
$('a.edit').click( function() {
var b;
$.ajax({
success: function() {
var c;
$(new_form).submit(function() {
var d;
$.ajax({
success: function(data) {
// a,b,c,d are all visible here.
// note that a references the same object for all calls of the success function, whereas d is a different variable for each call of submit.
// this behaviour is called closure: the 'enclosed' function has access to the outer var
}
})
})
}
})
})
Version two: less nested, but without closures and without variable access:
var a;
$('a.edit').click(onEdit);
var onEdit = function() {
var b;
$.ajax({success: onEditSuccess});
};
var onEditSuccess = function() {
var c;
$(new_form).submit(onSubmit);
};
var onSubmit = function() {
var d;
$.ajax({success: onSubmitSuccess});
}
var onSubmitSuccess = function(data) {
// a is visible (global var)
// b,c,d NOT visible here.
};
Version three: less nested and with unnamed functions and parameters to get access to the closure variables:
var a;
$('a.edit').click(function(){onEdit(a)});
var onEdit = function(a) {
var b;
$.ajax({success: function(){onEditSuccess(a,b)}});
};
var onEditSuccess = function(a,b) {
var c;
$(new_form).submit(function(){onSubmit(a,b,c)});
};
var onSubmit = function(a,b,c) {
var d;
$.ajax({success: function(data){onSubmitSuccess(data,a,b,c,d)}});
}
var onSubmitSuccess = function(data,a,b,c,d) {
// a,b,c,d are visible again
// nice side effect: people not familiar with closures see that the vars are available as they are function parameters
};
You can easily refactor this to make it much more readable. The key concept to grasp is that you can refer to named functions in callbacks as well as anonymous ones. So, for instance:
function clickHandler() {
alert("Link clicked");
}
$('a').click(clickHandler);
My preference is always to give the functions names according to what they do (e.g. loadImage, rather than the event that you intend to trigger them (e.g. clickLink. This makes your code clearer and makes later changes much easier. In this case, I would structure my code like this:
$(document).ready(function(){
$('a.edit').click(loadFormStart);
function loadFormStart() { // get form
$.ajax({
success: loadFormEnd
});
}
function loadFormEnd(data) { // add form & handler
$('new_form').submit(handleFormStart);
}
function handleFormStart() { // submit form
$.ajax({
success: handleFormEnd
});
}
function handleFormEnd(data) { // receive form data
//display message
}
});
I'd also advise you to read Code Organization on jqfundamentals which gives a similar approach to this using an object literal.
Interesting question. Personally I don't mind the above. Commenting is key, so you could consider qualifying the closing braces with some:
} //success: function(data)
}) //$.ajax({
}) //$(new_form).submit(
...etc
I would also look at aligning the brackets correctly (at first clance, your }} is a little mystifying).
If it comes to 'generic' nesting strategies, the only other suggestion I have is to move code out other functions. The of course means that you have the function decalred in memory, but may make it more readable.
You could also consider a specific strategy that relates to this code. For example, rather than manually binding a submit to new_form can you use the live function in some way to ensure that it is done automatically?
On a completely unrelated note, you should probably add some ; at the end of each of the bracketed lines!

Unable to change global variable from local function

I'm trying to have a jQuery.getJSON() call change a global variable with the JSON array it returns:
var photo_info ;
//Advance to the next image
function changeImage(direction) {
jQuery('img#preview_image').fadeOut('fast');
jQuery('#photo_main').css('width','740px');
if (direction == 'next') {
jQuery.getJSON('/ajaxupdate?view&sort='+sort+'&a='+a+'&s=' + title_url_next, function(data) {
photo_info = data;
title_url = photo_info.title_url;
title_url_next = photo_info.preview_title_url_next;
title_url_previous = photo_info.preview_title_url_previous;
});
} else if (direction == 'prev') {
jQuery.getJSON('/ajaxupdate?view&sort='+sort+'&a='+a+'&s=' + title_url_previous, function(data) {
photo_info = data;
title_url = photo_info.title_url;
title_url_next = photo_info.preview_title_url_next;
title_url_previous = photo_info.preview_title_url_previous;
});
}
}
However, the variable photo_info is only accessible from within the getJSON() function and returns undefined from anywhere else in the script.
What am I doing wrong?
as Randal said Ajax call is asynchronous. Use the ajaxComplete function or replace the getJSON function with an .ajax call and use the photo_info var whithin the success function e.g.:
$.ajax({
url: 'ajax/test.html',
success: function(data) {
$('.result').html(photo_info);
}
});
If you're looking at photoinfo in the rest of the script right after changeImage has returned, then of course it won't have a value, because the Ajax call is asynchronous. You need to rethink your application to be more event driven.
JavaScript scoping isn't quite like standard scoping. It looks like you're actually losing your scope because of nested functions. Try giving this article a read:
http://www.robertsosinski.com/2009/04/28/binding-scope-in-javascript/

Categories

Resources