Can someone tell why my object img is not accepting its value outside the ajax call? I've also used a constructor function to create the object but that did not work as well. And the xml parsed values work, I've tested this. If i move the alert(img.location) inside the success event the correct value will show, but it will not outside the ajax function..
Help please...
function getImage(){
img = new Object();
$.ajax({
type: "GET",
url: "hvimage.xml",
dataType: "xml",
success: function(xmlData){
var randImageId = Math.floor(Math.random()*3);
$(xmlData).find("image").each(function(index, e){
if(index == randImageId){
img.id = $(this).attr("id");
img.location = $(this).find("location").text();
img.answer = $(this).find("answer").text();
}
});
},
error: function(xmdData){
alert("error");
}
});
alert("test");
alert(img.location); //Keep getting undefined here..
}
Thanks again,
Wenn
Because your AJAX request is asynchronous, so the code that comes after it does not wait for the response before it runs.
Any code that relies on the successful response needs to be placed in, or invoked from within the success: callback.
function getImage(){
img = new Object(); // 1. create object
// 2. send request
$.ajax({
type: "GET",
url: "hvimage.xml",
dataType: "xml",
success: function(xmlData){
// 4. response is received, and callback runs
var randImageId = Math.floor(Math.random()*3);
$(xmlData).find("image").each(function(index, e){
if(index == randImageId){
img.id = $(this).attr("id");
img.location = $(this).find("location").text();
img.answer = $(this).find("answer").text();
}
});
},
error: function(xmdData){
alert("error");
}
});
// 3. fire alerts
alert("test");
alert(img.location); //Keep getting undefined here..
}
The reason you've having problems is that the code doesn't run in the sequence it seems you think it will.
The success function runs when the async request returns, whereas the last two alerts are triggered immediately after the request is sent. The data you want to use in those last two alerts simply isn't available to the browser yet.
Related
I am sending Ajax request to php page using Javascript.
My main goals is to send ajax request to PHP page and get the response which I have done that already.
The problem is when the Ajax send back the response the Javascript cannot send this to HTML properly.
Look at my code so you can understand clearly.
Javascript code:
function get_rental_fee(){
var count_model = $('#count_model').val();
for(var i =0; i < count_model; i++){
var hours = $('#hours').val();
var modelid = $('#modelid_multi'+i).val();
var get_tax = $('#get_tax_multi'+i).val();
var get_counter = $('#get_counter_multi'+i).val();
var myData = "hours="+hours+"&modelid="+modelid+"&get_tax="+get_tax;
jQuery.ajax({
type: "POST", // Post / Get method
url: "get_rental_fee.php", //Where form data is sent on submission
dataType:"text", // Data type, HTML, json etc.
data:myData, //Form variables
success:function(response){
var result = response.split('|');
document.getElementById('rental_price_multi'+i).value=result[0];
document.getElementById('tax_multi'+i).value=result[1];
},
error:function (xhr, ajaxOptions, thrownError){
//On error, we alert user
alert(thrownError);
}
});
}
}
The problem is here:
document.getElementById('rental_price_multi'+i).value=result[0];
document.getElementById('tax_multi'+i).value=result[1];
The loop runs 3 times and Php is sending me back the response 3 times. But in Javascript Theses 2 lines are only showing VALUES of 3rd Times not 1st and 2nd.
But I am receiving response of all 3 times.
Also when I run the code the javascript returns back an error:
Uncaught Type Error: Cannot set Property 'value' of null
Please help me where I am doing wrong
Problem is $.ajax is by default async: true, so the value of i in loop is not the desired value when it reaches success.
You can simply make the ajax sync:
$.ajax({
async: false,
...
})
Edited:
If you still want to it to be async, you need to use closures.
for(var i =0; i < count_model; i++){
(function(i){// closure `i`
$.ajax({
type: "POST",
...
});
})(i);//<-- for loop `i`
}
Your problem is that i inside the callback no longer has the value it did when you registered the callback. This is a very common problem.
A common solution is to "close over" the variable i so that it retains the correct value:
success: (function(i) {
return function(response) {
var result = response.split('|');
document.getElementById('rental_price_multi'+i).value=result[0];
document.getElementById('tax_multi'+i).value=result[1];
})(i)
The outer function is passed i as a parameter, at which point its value in the inner callback function becomes fixed.
I have an issue with a method ive created for an object ive created. one of the methods requires a callback to another method. the problem is i cant add the data to the object that called the method. it keeps coming back as undefined. otherwise when i send the data to the console it is correct. how can i get the data back to the method?
var blogObject = new Object();
var following = [...];
//get posts from those blogs
blogObject.getPosts = function () {
var followersBlogArray = new Array();
for (var i = 0; i < this.following.length;i++){
var followersBlog = new Object();
// get construct blog url
var complete_blog_url = ...;
i call the getAvatar function here sending the current user on the following array with it.
followersBlog.avatar = blogObject.getAvatar(this.following[i]);
that part goes smoothly
followersBlogArray.push(followersBlog);
}
this.followersBlogArray = followersBlogArray;
}
here is the function that gets called with the current user in following array
this function calls an ajax function
blogObject.getAvatar = function (data) {
console.log("get avatar");
var url = "..."
this ajax function does its work and has a callback function of showAvatar
$(function() {
$.ajax({
type: "GET",
dataType: "jsonp",
cache: false,
url: url,
data: {
jsonp:"blogObject.showAvatar"
}
});
});
}
this function gets called no problem when getAvatar is called. i cant however get it to add the data to the followersBlog object.
blogObject.showAvatar = function (avatar) {
return avatar
}
everything in here works fine but i cant get the showAvatar function to add to my followersBlog object. ive tried
blogObject.showAvatar = function (avatar) {
this.followersBlog.avatar = avatar;
return avatar
}
that didnt work of course. it shows up as undefined. can anyone help?
so somethings like...
$(function() {
$.ajax({
type: "GET",
dataType: "jsonp",
cache: false,
url: url,
complete: function () {
this.avatar = data;
}
data: {
jsonp:"blogObject.showAvatar"
}
});
});
}
Welcome to the world of asynchronous programming.
You need to account for the fact that $.ajax() will not return a value immediately, and Javascript engines will not wait for it to complete before moving on to the next line of code.
To fix this, you'll need to refactor your code and provide a callback for your AJAX call, which will call the code that you want to execute upon receiving a response from $.ajax(). This callback should be passed in as the complete argument for $.ajax().
The correct option for setting the JSONP callback is jsonpCallback. The recommendation from the API for .ajax(...) is to set it as a function.
{
// ...
jsonpCallback: function (returnedData) {
blogObject.showAvatar(returnedData);
},
// ...
}
I want to create a separate function to get specific data from Facebook graph JSON.
For example, I have the load() and called getNextFeed() function.
The getNextFeed works correctly. Except that returning value of aString is not successful.
When I pop alert(thisUrl). It said undefined.
Note: I am new to Javascript and Jquery. Please give me more information where I did wrong. Thank you.
function load()
{
$(document).ready(function() {
var token = "AccessToken";
var url = "https://graph.facebook.com/me/home?access_token=" + token;
var thisUrl = getNextFeed(url);
alert(thisUrl); // return undefined
});
function getNextFeed(aUrl)
{
$.ajax({
type: "POST",
url: aUrl,
dataType: "jsonp",
success: function(msg) {
alert(msg.paging.next); // return correctly
var aString = msg.paging.next;
alert(aString); // return correctly
return aString;
}
});
}
The problem is that $.ajax() is an ansynchronous function, means, when called, it returns in the same instance, but an ajax call is done in a separate thread. So your return vaule of $.ajax() is always undefined.
You have to use the ajax callback function to do whatever you need to do: Basically you already did it correctly, just that return aString does not return to your original caller function. So what you can do is to call a function within the callback (success()), or implement the logic directly within the success() function.
Example:
function load()
{
$(document).ready(function() {
var token = "AccessToken";
var url = "https://graph.facebook.com/me/home?access_token=" + token;
getNextFeed(url);
alert('Please wait, loading...');
});
function getNextFeed(aUrl)
{
$.ajax({
type: "POST",
url: aUrl,
dataType: "jsonp",
success: function(msg) {
alert(msg.paging.next); // return correctly
var aString = msg.paging.next;
alert(aString); // return correctly
do_something_with(aString);
}
});
}
I am still trying to figure all this out and I am coming across a really weird error.
I was using getJSON but after searching for solutions to this problem, I found that it was better to try to use the AJAX function (for error capturing -> which isnt firing).
Using breakpoints in firebug, if I go slowly through the running code, it works (mostly) fine (just need to change some coordinates for better drawing). But if I let it run at normal speed, it attempts to do the callback before the json object is returned. The firebug console says everything works ok (code 200), but when examining the jobj inside ship object/function it appears to be "undefined or null"
Following the breakpoints, the ajax calls seem to be going to "error" and not "success". But it isn't firing the alert...
Also, the response takes like 300-500ms.... is that normal? or do I need to find a better server?
Edited Code:
var init = (function(){
thisplayer = new player();
jQuery.ajax({type: "GET", url: "shipdata.php", processData: true, data: {shipid:1}, dataType: "json",
success: function(json) {
var pship = new ship(json);
player_ship = $.extend(thisplayer, pship);
starfield = new starfield();
for(var i = 0; i < player_ship.enemytotal; i++) {
$.ajax({
type: "GET",
url: "shipdata.php",
processData: true,
data: {shipid:Math.round((Math.random()*2+2))},
dataType: "json",
success: function(json) {
var enemy = new ship(json);
game.enemies.push(enemy);
},
error: function(x,y,z) {
// x.responseText should have what's wrong
alert(x.responseTest);
}
});
}
game.initialized = true;
},
error: function(x,y,z) {
// x.responseText should have what's wrong
alert(x.responseTest);
}
});
})
..............................
var ship = (function(json){
var self = this;
jobj = jQuery.parseJSON(json.responseText);
self.height = jobj.height;
self.width = jobj.width;
self.xinit = jobj.xinit;
self.yinit = jobj.yinit;
self.speed = jobj.speed;
self.weapons = jobj.weapons;
self.maxlasers = jobj.maxlasers;
self.imagesrc = jobj.imgurl;
self.lasers = [];
self.x = self.xinit;
self.y = self.yinit;
JSON being sent in:
{"height":75,"width":50,"xinit":275,"yinit":525,"speed":3,"weapons":[1,2],"maxlasers":2,"imgurl":"images\/ship.png"}
Live Demo:
http://www.schennshome.net/medicalmmj/practice/index.html (The code is far from being perfect, Im running through it to try and catch the various errors before animating, but cant get past this.)
I've dug through your source code, and the problem is not actually shown in your question. The problem is with this line, which follows your Ajax call:
player_ship = $.extend(thisplayer, game.pship);
game.pship refers to the data returned by the ajax call, but since this is asynchronous, the above line will be evaluated first, which means game.pship will not be defined.
To fix this, you need to include all of the code in your init function that is currently below the ajax call directly in the success callback. This will prevent the code from being evaluated until the ajax call has returned.
The reason that it works with breakpoints is that this interrupts evaluation, which allows the ajax call to complete before game.pship is referenced.
Edit
I'm now getting an error on line 489, stating that player_ship is undefined. This is again because of the evaluation order of async code. The problem is that player_ship is being defined inside the ajax function in init now, but is being referenced in gameLoop, outside of this callback.
This is how I would rewrite gameLoop:
var callback = function() {
game.canvas.clearCanvas();
drawStarfield();
if(player_ship.alive && game.initialized && !(game.loading)) {
drawPlayer();
drawLaser();
drawEnemies();
}
};
if(game.initialized==false) {
init(callback);
} else {
callback();
}
And then amend init to accept a callback method which is called at the bottom of your success callback. This way, if the game has not been initialized (and player_ship is not yet defined), it will be executed after the ajax call.
Here is a function that I have to write to an xml file through an ajax call. The code works fine the first time the ajax call is made. On the second each loop, the ajax call isn't made at all. I don't know why. I specified asyn to false. That did not help. That doesn't seem to be the problem anyway.
$('#'+divid).children('div').children('div').each(function () {
var url = $(this).find('a');
var urlname = url.text();
var urllink = url.attr('href');
var urlid = $(this).attr('id');
alert ("from javascript urlid: "+urlid+" urlname: "+urlname+" urllink: "+urllink);
$.ajax({
url: "add_url.php",
type: "POST",
data: { nodeid: divid, urlid: urlid, urlname: urlname, urllink: urllink },
cache: false,
async: false,
success: function (response) {
if (response != '')
{
alert(response);
}
}
});
});
This really works for me
http://jsfiddle.net/genesis/DTjZQ/4 (3 POST request sent with response status 404)
be sure that your html is good and with same structure as in my fiddle
Instead of making multiple AJAX requests, I suggest appending the data to an array and then sending the entire array of objects.
(Basically the literal object you're using for data would be appended to an array instead of used in a request, and then once the each is done, you would send the array as the data.)