javascript global variable not updating and ajax making same request - javascript

<script type="text/javascript">
// i need app Id and image name from json
var waypoint;
var count = 0;
var number = 0;
var url = '{{url("/app/next/")}}/' + number;
$(document).ready(function() {
loadMore();
$(window).scroll(function() {
$(window).scrollTop() + $(window).height() >
$(document).height() - 450 && 0 == count && (count = 1,loadMore())
})
});
function loadMore(){
$.getJSON(url, function(jd) {
jd.forEach(myFunction);
function myFunction(item, index) {
var app = '<a href="{{url('/app/')}}/'+item.id+'"/>';
$('#content').append(app);
number = item.id;
if(item.id == 1){
count = 1;
}
else{
count = 0;
}
}
return true;
});
}
</script>
Here i am looping threw rows from last to first in database with jquery.
my php script is set to give next last element in the row and working fine if i make the request manually.
http://theviralappcreate.dev/app/next/4 will return element number 3.
whenever i scrool down it makes request at : http://theviralappcreate.dev/app/next/0 and keeps making same request, however i am updating the number variable by number = item.id;

Just move
var url = '{{url("/app/next/")}}/' + number;
Inside loadmore()
function loadMore(){
var url = '{{url("/app/next/")}}/' + number;
$.getJSON(url, function(jd) {
...
then as number increments each request will use updated url value

Related

How do I compare new ajax output with previous using divs?

I decided to build a high/low game in javascript and am running into an issue where the numbers displayed are ahead of what the variables have stored or the exact opposite. I can't seem to get them to match.
EDIT: I figured it out, the code ran before ajax was done causing an offset.
It helps me more when I find answers with the old code to compare with the new so I'll leave the broken code. Updated with working code at the end.
Page that helped me figure out a fix:
Wait for AJAX before continuing through separate function
Original JavaScript:
var y = "0";
var z = "0";
var output_div = document.getElementById("outcome");
var last_ = document.getElementById("val");
var cardVal;
function higher(x) {
var new_ = last_.innerHTML; //getting new value
y = last_.getAttribute("data-old"); //getting old value
console.log("data_old " + y);
z = ajx(); //calling function return the value from which need to compare
console.log("data_new " + z);
if (x === 1) {
if (z > y) {
output_div.innerHTML = "Winner!";
} else {
output_div.innerHTML = "Loser!";
}
} else {
if (z < y) {
output_div.innerHTML = "Winner!";
} else {
output_div.innerHTML = "Loser!";
}
}
last_.setAttribute("data-old", new_); //setting old value with current value of div
}
function ajx() {
$.ajax({
url: "./getfacecard.php",
success: function(response) {
var result = $.parseJSON(response);
var img = result[0];
cardVal = result[1];
document.getElementById(\'card\').src = img;
document.getElementById(\'val\').innerHTML = cardVal;
}
});
return cardVal; // return current card value in calling function
}
Updated Working JavaScript:
var lastVal = document.getElementById("lastVal"); //Last played cars value
var wl = document.getElementById("outcome"); //Shows win or lose
var newVal = document.getElementById("currentVal"); //Current face up card
var iSrc = document.getElementById("card"); //Card img
var lVal; //Last cards value from post
var iLink; //Image link from post
var nVal; //Gets new html to be sent to post.
function start(x){
// console.log("Start:");
ajx(function(){ //Runs ajax before continuing
iSrc.src = iLink; //Set new card image src
newVal.innerHTML = nVal; //Sets Current card value in div
lastVal.innerHTML = lVal; //Sets Last card value in div
// console.log("-slgn"); //Consoles to track code launch order.
// console.log("-Last Value: "+lVal);
// console.log("-Current Value: "+nVal);
// console.log("-Link: "+iLink);
// console.log(x);
if(x===1){ //If clicked higher
if(nVal>lVal){ //If new card is higher than old card
wl.innerHTML = "Winner!";
}else{
wl.innerHTML = "Loser!"
}
}
if(x===2){
if(nVal<lVal){ //If new card is lower than old card
wl.innerHTML = "Winner!";
}else{
wl.innerHTML = "Loser!"
}
}
});
}
function ajx(callback) {
$.ajax({
type: "POST",
data: {data:newVal.innerHTML}, //Post new card value to be returned as last card.
url: "./getfacecard.php",
success: function(response) {
var result = $.parseJSON(response);
iLink = result[0]; //img
lVal = result[2]; //Last card
nVal = result[1]; //New Card
// console.log("ajax");
callback(); //Go back and the code
}
});
}
You can use custom attribute in your div to save your current value as old value and vice versa so only one div required here i.e: Your div look like below :
<div data-old="0" id="val">0</div>
And js code will look like below:
var y = "0";
var z = "0";
var output_div = document.getElementById("outcome");
var last_ = document.getElementById("val");
function higher(x) {
var new_ = last_.innerHTML; //getting new value
y = last_.getAttribute("data-old"); //getting old value
console.log("data_old " + y);
z = ajx(); //calling function return the value from which need to compare
console.log("data_new " + z);
if (x === 1) {
if (z > y) {
output_div.innerHTML = "Winner!";
} else {
output_div.innerHTML = "Loser!";
}
} else {
if (z < y) {
output_div.innerHTML = "Winner!";
} else {
output_div.innerHTML = "Loser!";
}
}
last_.setAttribute("data-old", new_); //setting old value with current value of div
}
function ajx() {
$.ajax({
url: "./getfacecard.php",
success: function(response) {
var result = $.parseJSON(response);
var img = result[0];
var cardVal = result[1];
document.getElementById('card').src = img;
document.getElementById('val').innerHTML = cardVal;
}
});
return cardVal; // return current card value in calling function
}
In above js code what i done is after ajax call finishes execution it will return cardVal which will get pass in variable z and then we will compare it with y i.e : old value and print required output.Also, i have return value from ajax called because when you do document.getElementById(\'val\').innerHTML = cardVal; still this value is not available with us in our function higher so to overcome this i have return that value to your calling function.
(This code is already tested and working as excepted )

Recursive function crashes when it loops many times javascript

I have this recursive function which is giving me some problems. It needs to be runned like 20.000 times, but when it loops many times the browser crashes. Any help is appreciated
var valid = 0, id = 0;
$(document).ready(function() {
$("#fetch").submit(function(event) {
event.preventDefault();
var selected = $(this).find("#site option:selected");
var pieces = selected.text().split("(");
var sitename = pieces[0];
var numbers = pieces[1].slice(0,-1).split("/");
var fetched = numbers[0]; var total = numbers[1];
var members = $(this).find("#members").val();
var time = $(this).find("#wait").val() * 1000;
wait = (time == 0) ? 800 : time;
$("progress").prop("value", 0).prop("max", members * 2).fadeIn();
valid = 0;
function fetchMember(id) {
id++;
$.post("script.php", $("#fetch").serialize() + "&id=" + id )
.done(function(data) {
console.clear();
isUser = ($(data).text().indexOf("Invalid User") == -1);
if (isUser) valid++;
if(valid < members) setTimeout(function(){ fetchMember(id) }, wait);
if (isUser) {
progress();
fetched++;
selected.text(sitename+"("+fetched+"/"+total+")"); //Updating numbers of fetched profiles on the frontend
username = $(data).find(".normal").text() || $(data).find(".member_username").text() || $(data).find("#username_box h1").text();
$(data).find("dt").each(function() {
var text = $(this).text();
if (text == 'Location') country = $(this).next("dd").text();
});
$.post("save.php", { username: username } )
.done(function(data) {
$("#test").append(id+" "+data + "<br />");
progress();
});
}
});
}
fetchMember(id);
});
});
The function needs to be repeated 20.000 times with a default interval of 800ms or even more like 10 minutes
This function isn't recursing, it's just using setTimeout to call itself again at some point in the future, which isn't the same as true recursion.
However, you're using a global variable passed into a function, this will be causing you scoping issues as it's passed as a copy. By passing the id in to the timed call, you're creating a closure, which at 20,000 times, may be causing you some issues.
That's 20,000 function calls you're pushing onto the stack. That is very memory-intensive.
Try if it is a memory issue but I don't see that looking at the code.
var valid = 0, id = 0;
$(document).ready(function() {
$("#fetch").submit(function(event) {
event.preventDefault();
var selected = $(this).find("#site option:selected");
var pieces = selected.text().split("(");
var sitename = pieces[0];
var numbers = pieces[1].slice(0,-1).split("/");
var fetched = numbers[0]; var total = numbers[1];
var members = $(this).find("#members").val();
var time = $(this).find("#wait").val() * 1000;
wait = (time == 0) ? 800 : time;
$("progress").prop("value", 0).prop("max", members * 2).fadeIn();
valid = 0;
fetchMember(id,selected,pieces,sitename,numbers,fetched,members,time,wait);
});
});
function fetchMember(id,selected,pieces,sitename,numbers,fetched,members,time,wait) {
id++;
$.post("script.php", $("#fetch").serialize() + "&id=" + id )
.done(function(data) {
console.clear();
isUser = ($(data).text().indexOf("Invalid User") == -1);
if (isUser) valid++;
if (isUser) {
progress();
fetched++;
selected.text(sitename+"("+fetched+"/"+total+")"); //Updating numbers of fetched profiles on the frontend
username = $(data).find(".normal").text() || $(data).find(".member_username").text() || $(data).find("#username_box h1").text();
$(data).find("dt").each(function() {
var text = $(this).text();
if (text == 'Location') country = $(this).next("dd").text();
});
$.post("save.php", { username: username } )
.done(function(data) {
$("#test").append(id+" "+data + "<br />");
progress();
if(valid < members) setTimeout(function(){ fetchMember(id,selected,pieces,sitename,numbers,fetched,members,time,wait) }, wait);
});
}
});
}
Memory leak references http://javascript.crockford.com/memory/leak.html ... jquery does not leak.
[Exhibit 4 - Leak test with a closure]
<html>
<head>
<script type="text/javascript">
function LeakMemory(){
var parentDiv = document.createElement("div");
parentDiv.onclick=function(){
foo();
};
parentDiv.bigString =
new Array(1000).join(new Array(2000).join("XXXXX"));
}
</script>
</head>
<body>
<input type="button"
value="Memory Leaking Insert" onclick="LeakMemory()" />
</body>
</html>

How to prevent a ajax function in javascript to be executed several times at once

I am building search engine with PLAY Framework 2.2.1 and have problems with listing the results. The search results are stored in the cache provided by the framework and can be accessed with the uniqe id. I don't want the results to get displayed all at once, so the result list is fetched in chunks via ajax.
The first part after the result site has loaded and the rest every time when a certain scroll event occurs.
Now the problem is that some of the results are listed several times and the alert messages
tell me that the function next_results sometimes gets executed with the same value for variable pos twice or more times.
To prevent this issue I use the processing variable but this doesn't seem to work properly.
var processing = false;
var not_finished = true;
var pos = 0;
function next_results(uuid, result_size){
alert("input\n" + result_size + " result_size\ncurrent_position" + pos);
jsRoutes.controllers.Application.getResults(uuid, pos, result_size).ajax({
success : function(data) {
var len = data.length;
// alert("input\n" + result_size + " result_size\ncurrent_position" + pos + "\n result_length" + len);
pos = pos + len;
if (len == 0){
not_finished = false;
} else {
for (var i = 0; i < len; i++) {
var result= data[i];
$('#results').append(result.string);
};
}
}
});
}
var uuid;
function set_uuid (x){
uuid = x;
}
$(document).ready(function(){
//initial
if (!processing){
processing = true;
next_results(uuid, 10);
processing = false;
}
$(document).scroll(function(e){
if (processing)
return false;
if (not_finished && $(window).scrollTop() >= $(document).height() - $(window).height() - 300){
processing = true;
next_results(uuid, 2);
processing = false;
}
});
});
The unique id is set in the html code (via Scala):
<script>set_uuid('#uuid');</script>
next_results(uuid, 2);
processing = false; <-- WRONG
You need to do it in the success function
success : function(data) {
...
...
processing = false;
}

My javascript doesn't run without alert

I am having a problem with a block of my code, this section creates boxes of chocolates based on what a user chooses in a previous step and what data is pulled from the database in the api script.
the problem is that it doesn't work without the alert('hi') in it. if i take that out it will just create an empty box without dropping the flavors in it, the flavor the flavors are inserted with the createFlavorArray function.
var product = new Array();
var price = new Array();
var size = new Array();
$(function () {
$.ajax({
type: 'POST',
url: 'phpscripts/api.php',
data: "",
dataType: 'json',
success: function(rows)
{
count = 0;
for (var i in rows)
{
var row = rows[i];
product[count] = row[0];
price[count] = row[1];
size[count] = row[2];
count++;
}
}
});
});
//b = box
//o = option that is inside the box
//nextBoxId is the box id
//nextFlavorId is the option or flavor id
var nextBoxId = 1;
var nextFlavorId = 1;
var orderCap = 0;
var subTotal = 0;
var numOfChocolates = 0;
var numOfBoxes = 0;
$(document).ready(function(){
while (halfPoundBoxes > 0) {
$("#boxes").append('<div id="b'+nextBoxId+'"></div>');
$('#b'+nextBoxId).addClass('div-table-selection');
$('#b'+nextBoxId).append($('#minusBox').clone().attr('id', "m"+nextBoxId));
$('#b'+nextBoxId).append('<div style="display:table-row"></div>');
//call the function to loop through and create the number of flavor options needed
var x = 0;
alert('hi');
while(x < product.length){
if ('1/2lb Box' == product[x]) {
createFlavorArray(size[x], nextBoxId);
subTotal += price[x] * 1;
$('#b'+nextBoxId).attr('title', product[x]);
}
x++;
}
//clone the delete box button and make it visible
$('#m'+nextBoxId).show(500);
$('#b'+nextBoxId).append("<br />");
if (orderCap == 0) {
$('#boxes').append('<div id="msg"><p>If you wish to add another box to your order select the size and click +1 Box.</p></div>');
}
$("#m"+nextBoxId).click(function() {
$(this).parent().remove();
orderCap--;
//if they're ordering zero boxes hide the order button
//remove total price
//remove the message
if (orderCap == 0)
{
document.getElementById('orderBtn').style.display = "none";
$("#msg").remove();
$("#totalPrice").empty();
}
if (orderCap < 10)
{
$("#cap").remove();
$("#addBox").show(500);
}
var y = 0;
while (y < product.length) {
if ('1/2lb Box' == product[y]) {
subTotal -= price[y] * 1;
numOfChocolates -= size[y] * 1;
}
y++;
}
$('#totalPrice').html("<p>Sub Total: " + subTotal + "</p>")
//subtract the new
$('#finalpaypal').val(subTotal);
});
nextBoxId++;
orderCap++;
numOfBoxes++;
$('#totalPrice').html("<p>Sub Total: " + subTotal + "</p>")
halfPoundBoxes--;
}
The reason your code is working only when using an alert(), is that the alert() action is giving your jQuery AJAX request a few seconds to return a value to your success() call back function.
You should move any code which is affected by your callout function, into the callout function also, so that this code runs in the correct order.
Alternatively you could not run your AJAX request asynchronosly by adding async:false, but as #Rocket has commented, this isn't recommended.
$.ajax({
async: false,
You need to put the code in a function and run it after the ajax success is finished
...
$(function () {
$.ajax({
type: 'POST',
url: 'phpscripts/api.php',
data: "",
dataType: 'json',
success: function(rows)
{
count = 0;
for (var i in rows)
{
var row = rows[i];
product[count] = row[0];
price[count] = row[1];
size[count] = row[2];
count++;
}
do_after_ajax();
}
});
});
function do_after_ajax(){
while (halfPoundBoxes > 0) {
$("#boxes").append('<div id="b'+nextBoxId+'"></div>');
$('#b'+nextBoxId).addClass('div-table-selection');
....
}
It looks like you're trying to operate on markup returned by your ajax. That code needs to be moved into the success callback of the ajax request. The reason the alert call makes it work is simply that it delays everything else long enough for the page to finish loading.

simple code to Show / Hide with cookie

Does anyone know a code as simple as possible to show / hide HTML.
With:
-Store the cookies option
-Effect to the Show / Hide
The jquery cookie plugin could simplify cookie management. As far as showing/hiding HTML is concerned you may take a look at the show() and hide() methods.
It really depends on the event/reason the content needs to show/hide...
Is it user specific content that must appear for a particular user, if so, how are you identifying the user (sessions, openID)?
Or is it event driven, ie, a user clicks on a button and content shows/hides and the cookie stores the show/hide state?
Damo
Probably more than you need, but I use this with the tablesorter plugin to collapse/expand sections of tables, store the state in the cookie and with .toggle() you can get a nice effect.
function tableContainer(id,visible,sortColumn,sortOrder){
this.ID = id;
this.Visible = visible;
this.SortColumn = sortColumn;
this.SortOrder = sortOrder;
}
function bindTableHeaders(element){
//Bind click handler to the table THs to update object as to current sort column.
$("thead th","#" + element).bind("click",function(){
var order = this.order
var column = this.column
var $table = $(this).closest("table")
var visible = $table.attr("expanded") //Technically I suppose if you can click these then it must be visible
var id = $table.attr("id")
var tableObj = new tableContainer(id,visible,column,order);
$.cookie(element, JSON.stringify(tableObj), { secure: true }); //Write the current state into the section cookie
});
};
function recoverState(element) {
// pull cookie for page state and visibility
var elementData = $.cookie(element);
if (elementData != null){
// parse JSON based on object representation
var json = JSON.parse(elementData)
var id = json.ID;
var visible = json.Visible;
var sortColumn = json.SortColumn == undefined ? 0 : json.SortColumn
var sortOrder = json.SortOrder == undefined ? 0 : json.SortOrder
} else {
var id = element;
var visible = "true"
var sortColumn = 0;
var sortOrder = 0;
}
// switch visibility
if(visible == "false"){
toggleElement(element)
}
// Determine if this section has any data (eg. a <tbody>)
if ($("tbody","#" + id).length == 0 || $("tbody","#" + id).html() == "")
return
if (pageAction == "Edit"){
$("#" + id).tablesorter({widgets: ['zebra'], sortList: [[sortColumn,sortOrder]]});
} else {
$("#" + id)
.collapsible("td.collapsible",{
collapse:true
})
.tablesorter({widgets: ['zebra'], sortMultiSortKey:'false', sortList: [[sortColumn,sortOrder]]});
}
}
function toggleElement(element) {
if ($("#" + element).attr("expanded") == "true"){
$("#" + element).attr("expanded","false")
$("#" + element).hide();
var isVisible = "false"
} else {
$("#" + element).attr("expanded","true")
$("#" + element).show();
var isVisible = "true"
}
//Rewrite the cookie for this section changing only the visibility
var elementData = $.cookie(element);
var visible = isVisible;
if (elementData != null){
var json = JSON.parse(elementData)
var id = json.ID;
var sortColumn = json.SortColumn;
var sortOrder = json.SortOrder;
} else {
var id = element
var sortColumn = 0;
var sortOrder = 0;
}
var tableObj = new tableContainer(id,visible,sortColumn,sortOrder);
$.cookie(element, JSON.stringify(tableObj), { secure: true }); //Write the current state into the section cookie
}

Categories