Trying to get the newest innerHTML text of a label - javascript

I have a function that queries a database for info, when a button is clicked. This info gets written to innerHTML of a label. When this function returns, I read the innerHTML of this label. Problem is, it always returns the old value, not the new value that was pulled from the database. The label on the scree is displaying the correct value, though. When I click the button again, the value that I was expecting on the previous click, is now given. Seems like a timing issue but can't seem to figure it out.
example:
SQL Data - cost = 10
I expect to see 10 alerted to me when I click the button. I get a blank alerted to me, even though 10 is now in the label. When I click the button again, 10 is alerted, but 20 is now in the label.
function getInfo() {
var ctlMonthly = document.getElementById("cellMonthlyCost")
getSQLData(ctlMonthly);
alert(ctlMonthly.innerHTML);
}
function getSQLData(ctlCell){
...
var my_ctlCell = document.getElementById(ctlCell);
$.each(objData.items, function() {
my_ctlCell.innerHTML = this.Param1
});
...
}
Thanks.

you need to add the alert after the data is received from the database. I am assuming that you're sending an ajax request to fetch data. You will be able to get the new value in the callback of you're ajax request function.
Currently what is happening in your code is that
1. getSQLData(ctlMonthly);
// This sends a request to the data base to fetch data
2. alert(ctlMonthly.innerHTML);
// This shows the current value in an alert
3. data is received and shown in the label
This process happens so fast that you don't notice the difference between step 2 and 3.

Is this what you want?
I used a callback function
function getInfo() {
var ctlMonthly = document.getElementById("cellMonthlyCost")
getSQLData(ctlMonthly,alertInfo);
}
function alertInfo(info){
alert(info);
}
function getSQLDate(ctlCell,callbackFn){
...
var my_ctlCell = document.getElementById(ctlCell);
$.each(objData.items, function() {
my_ctlCell.innerHTML = this.Param1;
callbackFn(this.Param1);
});
...
}

to piggyback on Himanshu's answer, your request to your server is async. Meaning javascript will execute the GET request and continue on with the script, when the requests comes back from the server it will run whatever callback you give it. ( i.e. update label tag )
assuming getSQLData is a ajax call or something promised based, something like:
function getSQLData(ctlCell){
return $.get('/sql/data').done(function () {
var my_ctlCell = document.getElementById(ctlCell);
$.each(objData.items, function() {
my_ctlCell.innerHTML = this.Param1
});
});
}
you can change your code to:
function getInfo() {
var ctlMonthly = document.getElementById("cellMonthlyCost")
getSQLData(ctlMonthly)
.done(function () {
alert(ctlMonthly.innerHTML);
});
}
Basically the difference is your telling javascript to alert the innerHTML after the requests comes back from the server.
The more correct answer would be to alert the data straight from the response instead of reading from the DOM.

Related

How to prevent refetching AJAX data?

I'm using javascript but not jQuery.
Let's say I have 3 users in my database [Kim,Ted,Box] and 3 buttons as below:
<button class="user">Kim</button>
<button class="user">Ted</button>
<button class="user">Box</button>
<div id="displayArea"></div>
If a person clicks on any of the buttons it will display the user information in the div.
Assume I click on the Kim button and it uses ajax and displays the information of Kim. And now I click Ted it also calls a new ajax function to get the data. But when I click Kim again I call the new ajax function to get the data rather than get the data from cache or some place. How can I achieve it without getting the data from ajax function if the data is loaded before?
The reason why I need this is because I don't want the user to wait to get the data again that they loaded before.
Add one level of abstraction by creating a function that takes care of the caching and either returns the data from the cache or makes an Ajax request. For example:
var getDataForUser = (function() {
/**
* We use an object as cache. The user names will be keys.
* This variable can't be accessed outside of this function
*/
var cache = {};
/**
* The function that actually fetches the data
*/
return function getDataForUser(user, callback) {
if (cache.hasOwnProperty(user)) { // cache hit
callback(cache[user]);
} else {
// somehow build the URL including the user name
var url = ...;
makeAjaxRequest(url, function(data) { // cache miss
cache[user] = data; // store in cache
callback(data);
});
}
};
}());
Then you make the call
getDataForUser('John', function(data) { /*...*/ });
twice and the second time it will hit the cache.

getJSON jQuery won't fill object

So I've got some code that retrieves a series of objects from an API. When I try to store them in a global variable, it doesn't seem to do anything. Here's the code:
var current_corpus = {};
function page_init() {
$.getJSON("http://resource1.com", function(data) {
populate_collections(data);
populate_citations(data);
});
}
function populate_collections(collections) {
$.each(collections, function (i, item) {
current_corpus[item] = [];
});
}
function populate_citations(collections) {
$.each(collections, function (index, collection) {
$.getJSON("http://resource2.com/" + collection.collection_id, function(data) {
current_corpus[collection] = data;
console.log(current_corpus);
});
});
}
When this finishes, current_corpus is completely empty. Logging these items verifies that they're being returned from the resources I'm posting to. I think there's just something about the asynchronous nature of these calls that I'm missing.
The line
current_corpus[item] = [];
is superfluous I think as the line
current_corpus[collection] = data;
should do the same thing while also tying data to the key object. Either way at the end of these functions running trying to access current_corpus via the console just gives me back an empty object.
Resources for dealing with AJAX stuff like this would be appreciated as well.
It all depends on what you want to do when the ajax requests complete. The A in ajax stands for Asynchronous meaning that such requests are non-blocking -- i.e. they will run in the background as control moves to the next line. Which explains why you're seeing an empty object right after the functions that invoke the ajax requests.
You can confirm that your code is working fine or you can do something once all the requests complete by using the following code snippet:
$(function() {
$(document).on('ajaxStop', function() {
console.log( current_corpus );
//do something with the now fully constructed object
});
});

Using GET method to get href attribute of an object

What i'm trying to do is what i thought would be quite easy, but it doesnt seem to be working. I want to get the href of an object and all the function is returning is undefined.
This is the page that i'm requesting and what i'm trying to retrieve is the href held in the element of the first seller (who's ClassName is ui-link-inherit)
var buy = $.get(
"http://m.roblox.com/items/24826737/privatesales/",
function (data){
alert($(data).find(".ui-link-inherit:eq(0)").attr('href'));
}
);
I thought it was a permissions issue at first but it still wont work even if you run that on the page.
Did you tried to just alert the data you get?
If there is no .ui-link-inherit ofc it wont work and since .ui-link-inherit seems to be a class of jqueryUI which adds the classes after the page is loaded via javascript, you wont get this class via GET
//EDIT: I dont get all this "you cant access the data cause ajax is asynchronus". He is using the get-fukction completely right. He can access data since data IS the returned stuff from the server. Did I miss something that you all get this that way?
You cannot return a value from that function, it is executed asynchronously. Instead just wait for the AJAX to finish and then do something with the result
// don't do this
// var buy = $.get(... etc...);
// the variable buy will never have any value
// do this instead
function getHREF(){
$.get(
"http://m.roblox.com/items/24826737/privatesales/",
function (data){
var buy = $(data).find(".ui-link-inherit:eq(0)").attr('href');
doSomething(buy);
}
);
)};
function doSomething(buy) {
// in here do whatever you want with the ajax data
}
$(document).ready(function () {
getHREF();
});
The site does not allow Cross-site HTTP requests. Read here: HTTP access control

Problem with removing child

I have two drop down forms. When the first is "changed" the second is populated with some data via ajax.
It's work but the value of the second drop down is not cleared on every request (I'm using $('#second_drop_down').children().remove();)
Here is sample code
$('#first_drop_down').live('change', function() {
var x = "some ajax data recived via ajax";
$('#second_drop_down').children().remove();
$('#second_drop_down').append(f);
});
Here you have a code that works, but it is practically like yours (you have a mistake in your example, 2 differente variables "x" and "f"):
http://www.jsfiddle.net/dactivo/8jfHG/
var timeChanged=1;
$("#first_drop_down").change(function()
{
$("#second_drop_down").children().remove();
$("#second_drop_down").append("<option value=\"volvo\">Volvo"+
timeChanged+
"</option><option value=\"saab\">Saab"+ timeChanged+
"</option><option value=\"mercedes\">Mercedes"+ timeChanged+"</option>");
timeChanged++;
});
Probably the code you received by ajax is malformed (I suppose).
Do you make a synchronous Ajax call? If not, you must put the code that changes the second drop down in the callback function, otherwise you will work on data that was not yet received. Assuming you use jQuery:
$.get( 'http://www.example.com', {first:$('#first_drop_down').val()},
function(data) {
$('#second_drop_down').children().remove();
$('#second_drop_down').append(data);
});

Modifying the DOM based on an AJAX result with jQuery

I'm unsure of the best practice for modifying the DOM based on an ajax response. I'll try to let the code do the talking because it's hard to explain.
// page has multiple checkboxes
$("input[type='checkbox']").live('click', function {
var cb = $(this); // for the sake of discussion i need this variable to be in scope
$("form").ajaxSubmit({ dataType: "script" });
}
The server sends a response back, and the js gets eval'd and that means "cb" is out of scope.
What I've done so far is create a couple of helper functions:
var target = undefined;
function setTarget(val) {
target = val;
}
function getTarget() {
return target;
}
And that turns the first snippet of code into this:
// page has multiple checkboxes
$("input[type='checkbox']").live('click', function {
setTarget($(this));
$("form").ajaxSubmit({ dataType: "script" });
}
Then on the server's response I call getTarget where I need to. This seems hackish... Any suggestions?
It's unclear what you're actually trying to do, but I feel like you want to be looking at the success parameter for that AJAX call. The success callback function should execute in parent scope and do what you're looking for.
See 'success' on this page in the jQuery docs.
So what you are trying to do is get the form to submit the content via ajax whenever the user checks/unchecks a checkbox? And because there are several checkboxes, you need to find out which one triggered the submit, so you can change its value to whatever is stored on the server?
If you submit the entire form everytime, why don't you reply with all the checkboxes values, and then change each and every one of them? If not, get the server to reply with the id and the value of the checkbox, then use jquery to find the checkbox with that ID and then change it's value.
How about:
jQuery(function($) {
// give it scope here so that the callback can modify it
var cb,
cbs = $('input[type="checkbox"]');
cbs.live('click', function {
// taking away var uses the most recent scope
cb = $(this);
// disable checkboxes until response comes back so other ones can't be made
cbs.attr('disabled', 'true'); // 'true' (html5) or 'disabled' (xhtml)
// unless you are using 'script' for something else, it's best to use
// a callback instead
$('form').ajaxSubmit({
success : function(response) {
// now you can modify cb here
cb.remove(); // or whatever you want
// and re-enable the checkboxes
cbs.removeAttr('disabled');
}
});
}
});

Categories

Resources