I just want to use a variable from outside of the function, but I am not sure what I have to do for that...
Is var myRequest = a; line enough to use this variable in the function?
Because I saw such an example: var myRequest = e.which;
I am asking this because I did not get a succesful result for my request.
I am think that it is not working as I expected because ajaxFunction(3) working diffirent than writing send.php?goto=3 into address bar of my browser.
You can see the following codes:
function ajaxFunction(a)
{
var ajaxRequest;
try {
ajaxRequest = new XMLHttpRequest();
} catch (e) {
try {
ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
alert("Your browser broke!");
return false;
}
}
}
ajaxRequest.open("GET", "send.php?goto=" + a, true);
ajaxRequest.send();
}
If you want to use a variable outside a function you have to use a global scope variable, example (using jQuery ajax)
var globalA = null;
$(document).ready(function(){
var localA1 = null;
$.ajax({
"url":"http://someurl.com/",
"type":"POST",
"dataType":"json",
"success":function(incomingData){
var localA2 = incomingData //localA2 only useable inside this function
localA1 = incomingData; //localA1 being set here still can only be used here as code within the "ready" function has already been executed and will see it as null
globalA = incomingData; //Now any further code should use globalA as it now contains useable data
doSomethingWithData();
},
"error":function(xhr,msg) {
alert("Ajax Error:"+msg);
}
});
alert(localA1); //Will give alertbox with null in it as localA1 has not been set.
});
function doSometingWithData() {
alert(globalA); //You can now use the data in whatever function makes reference to globalA
}
Of course in this example you could have just passed the data straight to doSomethingWithData() and processed it there.
You could take a look at the jQuery $.globalEval for instantiating a variable globally inside of your AJAX success function.
$.ajax({
url: "send.php",
success: function (data) {
$.getScript("somescript.js", function(data) {
$.globalEval("var something = new Whatever;");
});
});
The $.getScript portion is a helpful little snippet if you find you need to load an external JS file in your ajax call, and make its assets globally available. You can then use $.globalEval to instantiate a variable inside of your AJAX function.
Documentation for $.globalEval
Documentation for jQuery AJAX
You don't a function wrapper for setting a value to a variable.
var myRequest = a;
That is good enough.
After thought revision
in a very basic way a variable can be created on its own like a place holder.
var myRequest;
when you get to the function (say you have a series of functions.
You could do something like this.
function(myRequest=a);
if the function has more than one argument it can look like this.
function(myRequest=a,myConcern=b); as you have it stated in the
var arg1 = 1;
var arg2 = 2;
var arg3 = 3;
ajaxRequest.open(arg1,arg2,arg3);
I hope this is helpful and yes, some more info would help (like the poster below stated).
Related
I am working on setting up an HTML5 GeoLocation script and I would like to store the zip code in a cookie but for now I am just trying to figure out how to pass the zip code variable into another function.
Here is my script to reverse geo-code based on lat/long:
function retrieve_zip(callback)
{
try { if(!google) { google = 0; } } catch(err) { google = 0; } // Stupid Exceptions
if(navigator.geolocation) // FireFox/HTML5 GeoLocation
{
navigator.geolocation.getCurrentPosition(function(position)
{
zip_from_latlng(position.coords.latitude,position.coords.longitude,callback);
});
}
else if(google && google.gears) // Google Gears GeoLocation
{
var geloc = google.gears.factory.create('beta.geolocation');
geloc.getPermission();
geloc.getCurrentPosition(function(position)
{
zip_from_latlng(position.latitude,position.longitude,callback);
},function(err){});
}
}
function zip_from_latlng(latitude,longitude,callback)
{
// Setup the Script using Geonames.org's WebService
var script = document.createElement("script");
script.src = "http://ws.geonames.org/findNearbyPostalCodesJSON?lat=" + latitude + "&lng=" + longitude + "&callback=" + callback;
console.log(script.src);
// Run the Script
document.getElementsByTagName("head")[0].appendChild(script);
}
function callback(json)
{
zip = json.postalCodes[0].postalCode;
country = json.postalCodes[0].countryCode;
state = json.postalCodes[0].adminName1;
county = json.postalCodes[0].adminName2;
place = json.postalCodes[0].placeName;
alert(zip);
}
$('#findLocation').click(function(event) {
event.preventDefault();
console.log(zip); // This is giving me undefined currently
});
So basically, in the callback function, I want to store the zip code as a variable(rather than displaying it in an alert) and then in the on click function at the bottom, I want to be able to display the zip code that was stored in the previous callback function.
Any help greatly appreciated, still pretty new to Javscript/jQuery, thanks!
You could set zip as a 'global' variable by including it outside of the function at the top of the document like so:
var zip;
...
Alternatively, you may consider defining an object at the 'global' level and using it as a namespace to store variables like so:
window.address = {};
function callback(json){
address.zip = json.postalCodes[0].postalCode;
address.country = json.postalCodes[0].countryCode;
address.state = json.postalCodes[0].adminName1;
address.county = json.postalCodes[0].adminName2;
address.place = json.postalCodes[0].placeName;
}
$('#findLocation').click(function(event) {
event.preventDefault();
console.log(address.address);
console.log(address.zip);
...
});
I hope this helps!
Define var zip at very begining of code. You haven't defined it.
I haven't tried, but it should solve your problem.
Also, it seems that you forgot to define other variables in callback function as well.
What I would do, is to avoid the anonymous function in the event handler, that is, create a new named function -which gives you the added benefit of traceability during debugging- and then use that function as the event handler callback:
function eventHandlerFunction(event) {
var zip;
event.preventDefault();
zip = eventHandlerFunction.zip;
console.log(zip);
}
function callback(json) {
var zip;
zip = doSomethingWithJsonToGetTheZip();
eventHandlerFunction.zip = zip;
}
$("#findLocation").click(eventHandlerFunction);
Or, better yet, code this as a module and then you have member encapsulation and you can share variables amongst functions without modifying the global object. You never know when another library will modify the same global member that you are using.
var yourModule = (function($) {
var zip;
function retrieveZip(callback) {
// your code
}
function callback(json) {
// do something with json
zip = json.zip; // or whatever
}
$("#findLocation").click(function(event) {
event.preventDefault();
console.log(zip); // zip is visible in the parent scope + this scope
});
}(jQuery));
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.
I'm discovering the concept of "objects" in JavaScript. I'm making an RSS Parser, and I have an error (commented).
function MyParser (feed_url) { // Construct
"use strict";
this.feedUrl = feed_url;
this.pubArray = [];
if (typeof (this.init_ok) == 'undefined') {
MyParser.prototype.parse = function () {
"use strict";
var thisObj = this;
$.get(this.feedUrl, function (data, textStatus, jqXHR) {
if (textStatus == 'success') {
var xml = jqXHR.responseXML,
//lastBuildDate = new Date($(xml).find('lastBuildDate').text());
items = $(xml).find('item');
items.each(function () {
var pubSingle = thisObj.makeObj($(this).find('pubDate').text(),
$(this).find('link').text(),
$(this).find('title').text(),
$(this).find('description').text(),
$(this).find('encoded').text(),
$(this).find('commentRss').text(),
$(this).find('comments').last().text());
thisObj.pubArray.push(pubSingle);
});
console.log(thisObj.pubArray); // OK
}
}, 'xml');
console.log(this.pubArray); // Empty
return (this.pubArray);
};
MyParser.prototype.makeObj = function (pubDate, pubLink, pubTitle, pubDesc, pubContent, pubComCount, pubComLink) {
"use strict";
var pubSingle = {};
pubSingle.pubDate = new Date(pubDate);
pubSingle.pubLink = pubLink;
pubSingle.pubTitle = pubTitle;
pubSingle.pubDesc = pubDesc;
pubSingle.pubContent = pubContent;
pubSingle.pubComCount = pubComCount;
pubSingle.pubComLink = pubComLink;
return (pubSingle);
};
}
this.init_ok = true;
}
If you look at the console.log(), you'll see that the line // OK is outputting my array correctly.
But later, when returning from $.get, my array is empty.
Does anybody have an idea why, and how to correct that please?
This is not a problem with variable-scope. The problem here is that you're working with asynchronous flow and you're not thinking correctly the flow.
Let me explain:
When you do your .get, you fire a parallel asynchronous process that will request information from the browser, but your main program's flow keeps going, so when you get to your "return" statement, your array has not been filled yet with the response from your get method.
You should use your array from inside the get callback and not outside of it, since you can't guarantee that the array will have the information you need.
Does it make any sense?
Let me know!
Further explanation
According to your comments, you're still doing something like this:
var results = MyParser(feed_url);
//code that uses results.pubArray
And you cannot do that. Even though you're setting your "pubArray" inside your .get callback, you're trying to use pubArray right after you called MyParser and that's before the .get callback is called.
What you have to do, is call your next step on your program's logic from within the .get callback... that's the only way you can be sure that the pubArray is filled with proper data.
I hope that makes it clearer.
This is because your line
console.log(this.pubArray); // Empty
is being called directly after you issue your Ajax request; it hasn't had time to fetch the data yet. The line
console.log(thisObj.pubArray); // OK
is being called inside the Ajax callback, by which time the data has been fetched.
Thank you all, and particulary #Deleteman .
Here is what I did:
$.get(this.feedUrl, 'xml').success(function () {
thisObj.handleAjax(arguments[0], arguments[1], arguments[2]);
$(document).trigger('MyParserDone');
}).error(function () {
$(document).trigger('MyParserFailed');
});
Then, when i enter "HandleAjax", i'm back in my object context, so "this" refers to my object and the right properties. The only "problem" is that I have to set a listener (MyParserDone) to make sure the parsing is finished.
I am currently in the process of making my first Titanium iPhone app.
In a model I got:
(function() {
main.model = {};
main.model.getAlbums = function(_args) {
var loader = Titanium.Network.createHTTPClient();
loader.open("GET", "http://someurl.json");
// Runs the function when the data is ready for us to process
loader.onload = function() {
// Evaluate the JSON
var albums = eval('('+this.responseText+')');
//alert(albums.length);
return albums;
};
// Send the HTTP request
loader.send();
};
})();
and I call this function in a view like:
(function() {
main.ui.createAlbumsWindow = function(_args) {
var albumsWindow = Titanium.UI.createWindow({
title:'Albums',
backgroundColor:'#000'
});
var albums = main.model.getAlbums();
alert(albums);
return albumsWindow;
};
})();
however it seems like the call to the model (which fetches some data using HTTP) doesn't wait for a response. In the view when I do the alert it haven't received the data from the model yet. How do I do this in a best-practice way?
Thanks in advance
OK,
Something like this,
function foo(arg1, callback){
arg1 += 10;
....
... Your web service code
....
callback(arg1); // you can have your response instead of arg1
}
you will call this function like this,
foo (arg1, function(returnedParameter){
alert(returnedParameter); // here you will get your response which was returned in above function using this line .... callback(arg1);
});
so here arg1 is parameter (simple parameter like integer, string etc ... ) and second argument is your call back function.
Cheers.
What you need is Synchronous call to web service, so that it will wait till you get the response from the service.
To achieve this in java script you have to pass callback function as parameter and get the return value in callback function instead of returning value by return statement.
Actually coding style you are using is new for me because i am using different coding style.
But the main thing is you have to use call back function to retrieve value instead of return statement. Try this and if you still face the problem than tell me i will try to give an example.
the callback way like zero explained is nicely explained, but you could also try to get it handled with events.
(function() {
main.ui.createAlbumsWindow = function(_args) {
var albumsWindow = Titanium.UI.createWindow({
title:'Albums',
backgroundColor:'#000'
});
var status = new object(), // eventlistener
got_a_valid_result = false;
// catch result
status.addEventListener('gotResult',function(e){
alert(e.result);
got_a_valid_result = true;
});
// catch error
status.addEventListener('error',function(e){
alert("error occured: "+e.errorcode);
git_a_valid_result = true;
});
var albums = main.model.getAlbums(status);
// wait for result
while (!got_a_valid_result){};
return albumsWindow;
};
})();
and your model may something like
main.model.getAlbums = function(status) {
var loader = Titanium.Network.createHTTPClient();
loader.open("GET", "http://someurl.json");
loader.onload = function() {
var albums = eval('('+this.responseText+')');
status.fireEvent('gotResult',{result:albums});
return albums;
};
loader.onerror = function(e){
status.fireEvent('error',{errorcode:"an error occured"});
};
// Send the HTTP request
loader.send();
};
Just as a suggestion, try to use JSON.parse instead of eval as there are risks involved with using eval since it runs all javascript code.
I think that the solution The Zero posted is likely better for memory management, but I'm not totally sure. If you do and eventListener, be aware of the following
(see https://wiki.appcelerator.org/display/guides/Managing+Memory+and+Finding+Leaks)
function doSomething(_event) {
var foo = bar;
}
// adding this event listener causes a memory leak
// as references remain valid as long as the app is running
Ti.App.addEventListener('bad:idea', doSomething);
// you can plug this leak by removing the event listener, for example when the window is closed
thisWindow.addEventListener('close', function() {
// to remove an event listener, you must use the exact same function signature
// as when the listener was added
Ti.App.removeEventListener('bad:idea', doSomething);
});
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/