Trying to increment a javascript counter when using polling ajax http requests - javascript

I have a script that is running every 5 seconds, as a polling ajax http request.
I want to send an incrementing amount through it, on each request (1,2,3,4,5,6 etc...)
I have this so far, but the code just sends '1' through all the time.
// set the value to 1
var state = {
recordId: 1
};
$.ajaxPoll({
url: "map-service.cfc?method=getpoints",
type: "POST",
data: state,
dataType: "json",
successCondition: function(location) {
// return result != null; // custom condition goes here.
// increment it by 1
state.recordId = state.recordId +1
alert(state.recordId)
}
Does anyone know how to submit an increasing value through the 'data' param in the POST?

You have to make sure you are not setting the state.recordId over and over again each time you execute the function that calls the .ajaxPoll() method. state = ... should be in a parent scope of the function that runs .ajaxPoll() maybe something like this:
(function() { // <== Our scope
// set the value to 1 only once!
var state = {
recordId: 1
};
// The function that runs the poll. Do not set recordId to 1 inside here!
var callPoll = function() {
$.ajaxPoll({
url: "map-service.cfc?method=getpoints",
type: "POST",
data: state, // state.recordId will be 1, 2, 3, ...
dataType: "json",
successCondition: function(location) {
// return result != null; // custom condition goes here.
// increment it by 1
state.recordId = state.recordId +1
alert(state.recordId)
}
});
};
$(function() { // <== on doc ready
// Your functionality etc...... for example:
setInterval(callPoll, 1000);
});
}()); // <== Execute the anonymous function we're using as our scope

Probably a copy of state object is closed inside the anonymous function which will always start with it's initial value unless the changes are made outside of closure before it's closed/created. For verification just replace that incremental line with following
window.recordId = window.recordId + 1 // Making it global variable
You can find a very basic introduction to closures here http://msdn.microsoft.com/en-us/magazine/cc163419.aspx
Can you pass state object as a variable to successCondition anonymous function? That way you will always get the actual copy

You could also set a data variable to the document or body and increment that.
$('body').data('recordId', 1);
$.ajaxPoll({
url: "map-service.cfc?method=getpoints",
type: "POST",
data: {recordId: $('body').data('recordId')},
dataType: "json",
successCondition: function(location) {
// return result != null; // custom condition goes here.
// increment it by 1
newRecord = $('body').data('recordId');
$('body').data('recordId', newRecord+1);
alert($('body').data('recordId'));
}
});

Related

ajax reading/getting variable sometimes cannot get the exact variable with codeigniter

I am having a problem in my ajax or i don't know if it is a problem with ajax. I have an ajax code to get a value from label and concat it in my fresh data from database. Everytime i refresh the page, it outputs different. Sometimes it works fine, and sometimes it doesn't.
I am having my trouble in this part :
else {
value = value + "-"+init;
$('#checkID').text(value);
$("#checkID").css('visibility','visible');
}
sometimes it outputs 1-0 and sometimes the output became -0.
I am thinking of var value = $('#clinicID').html(); cannot concat with my -0 where the 1 of the output 1-0 is came from value variable
Here is my ajax full code :
function getcheckupID() {
var init = 0;
var value = $('#clinicID').html();
$.ajax ({
url: siteurl+"myclinic/getcheckID",
type: "GET",
dataType: "JSON",
success: function(data) {
if(data.length>0) {
$('#checkID').text(data[0]['check_up_id']);
$("#checkID").css('visibility','visible');
}
else {
value = value + "-"+init;
$('#checkID').text(value);
$("#checkID").css('visibility','visible');
}
}
})
}
my document ready code:
$(document).ready(function() {
get_clinicID();
show_patients();
checkupme();
});
where checkupme() function got a nested getcheckupID() runtime
I suggested another way to get data in #clinicID that you can use
When you refresh the page, insert your #clinicID like:
<span id="clinicID" data-value="1-0"><span> or whatever data you wanna input.
Then in getcheckupID function you'll call:
function getcheckupID() {
var init = 0;
var value = $('#clinicID').attr("data-value");
// Your code ajax
}
If it still have problem, please check your echo when page generated. Maybe there're not any value to print.
Hope this help.

Handling multiple setinterval javascript [duplicate]

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 7 years ago.
So I'm trying to build a web application that will ping a device's registers for stored data every 30 seconds.
as you can see each device can have multiple registers. When a user creates a new device I iterate all the newly created register id's that I return from my ajax post(generated DB id's) and then start an interval timer making an ajax call every 30 seconds to a method that will ping my device and get the data for the specific register.
The problem I'm running into is that every time the interval runs my ajax call, it's reusing the last register id to fetch data instead of running a fetch on each individual register. Ex. my 2 rows have an id of 22 and 23. Everytime my interval function is called it will use id 23 and make the ajax call instead of calling 22 then 23. Is this because I'm using a for loop when instantiating a new interval?
Here is how I try to handle my setInterval:
var registers = result.register_ids;
for (var i = 0; i < registers.length; ++i) {
debugger;
var interval = setInterval(function () { fetchRegisterValues(registers[i], result.modbus_id) }, 30000);
register_ping_threads[registers[i]] = interval;
}
Here is my ajax call to read the specified register:
function fetchRegisterValues(register_id, modbus_id) {//id always ends up being 23
debugger;
$.ajax({
type: "POST",
url: "/fetch_mdata",
data: {
'csrfmiddlewaretoken': token,
'register_id': register_id, //use to read the register range
'modbus_id': modbus_id //used to get device connectiong settings
},
contentType: "application/x-www-form-urlencoded",
dataType: 'json',
success: function (result) {
debugger;
$('[data-register="' + register_id + '"]').find('[data-value=""]').text(result.value);
},
error: function (data) {
debugger;
$('#loading-icon').hide()
$('#ping_error').addClass('alert alert-danger');
$('#ping_error strong').append('Problem contacting server..');
}
});
}
This is a very common mistake in JavaScript. Remember that i is in a scope of a function, not the scope of the loop, so all your fetchRegisterValues will reuse the same value of i. To fix it, create a new scope:
for (var i = 0; i < registers.length; ++i) {
debugger;
var interval = setInterval((function (i) { return function() { fetchRegisterValues(registers[i], result.modbus_id) } })(i), 30000);
register_ping_threads[registers[i]] = interval;
}

Interrupting an looping function

I trigger the following function when a tooltip is clicked. It is an ajax poll.
There can be many tooltips on the page, and more than one can need access to the data retrieved from the server.
What I want to achieve is to have this poll running as one instance - so if the user clicks a different tooltip the polling stops, rather than being duplicated.
Would be grateful if you could help.
Thanks
function doConversationsAjaxLongPoll(tablename){
clientSubmit = new Object;
// HERE WE'RE GOING TO GET A LIST OF THE ROWIDS THAT WE NEED TO POLL FOR, MAKE AN OBJECT OUT OF THEM. DO THIS BY LOOKING AT WHICH //TOOLIPS HAVE CLASS OPEN
var tooltips = [];
$('.tooltipOpen').each(function(index){
tooltips.push($(this).data('idrow'))
})
console.log("tooltips length: " + tooltips.length)
if(tooltips.length==0){
// console.log("tooltip length is 0 so we're returning false")
return false
}
clientSubmit.OpenConversations = tooltips
clientSubmit.tablename = tablename
clientSubmit.CurrentData = $('body').data('conversations')
console.log(clientSubmit)
$.ajax({
type: 'POST',
url: '/conversations.php?loadNew=1',
data: clientSubmit,
timeout: 25000,
success: function(data){
console.log('success')
data=JSON.parse(data)
console.log(data)
$('body').data('conversations', data)
},
complete: function(status, jqXHR){
if(tooltips.length==0){
// console.log("tooltip length is 0 so we're returning false")
return false
}
else
{
doConversationsAjaxLongPoll(tablename);
}
}
});
updateConversations()
}
I don't doubt that there are faaaar better ways of doing this but I have worked around the problem by having a random number generated by the click function, stored in $('body').data('random') which is then passed to the poll function. When the poll function loops it checks if the random number it was passed matches the one in data-random and returns false if it doesn't.

When should I use dojo.data.ItemFileWriteStore's _saveEverything function?

I am using dojo 1.6 version. My understanding is: if store._saveEverything = saveCompleteCallback; is defined, then the callback function saveCompleteCallback will be called only when store.save() is called?
And do I need to use the 1st and 2nd params defined in the callback function saveCompleteCallback(saveSuccess, saveFail, storeData){}? Cause I only know that I need to use them when calling store.save({onComplete: saveSuccess, onError: saveFail})?
First I only use _saveEverything when I need a dojox.data.dataGrid's data to be xhrPosted and then xhrGeted.
Assume you define: store._saveEverything = saveCompleteCallback;
I just figured out, that including the 1st and 2nd params of saveCompleteCallback(saveSuccess, saveFail, storeData) are necessary, because an extra saveSuccess() and saveFail() function needs to be called again in saveCompleteCallback(). e.g.
// When you wanna upload datagrid, you click upload button
Store.save({ onComplete : saveSuccess, onError : saveFail });
// Definition of saveCompleteCallback
function saveCompleteCallback(saveSuccess, saveFail, storeData) {
dojo.xhrpost(
url: posturl,
postData:storeData,
load: function(data) {
// saveSuccess() must be invoked here again,
// otherwise this function will not be called
saveSuccess();
}
);
}
function saveSuccess() {
dataGrid = dijit.byId('YOUR DATAGRID ID');
dojo.xhrGet(
url: geturl,
load: function(date){
// The reason that a new xhrGet is called is db data is updated
// So the dataGrid will have no value after xhrPost
var store = new dojo.data.ItemFileWriteStore({data: data});
store._saveEverything = saveEverything;
store.clearOnClose = true;
store.urlPreventCache = true;
dataGrid.setStore(store);
}
);
}

Loading additional modals from server with Paginator.clientPager

I'm trying to load additional modals from the server after the initial fetch with Paginator.clientPager
This is my collection, pretty much copy pasted from the example code on github.
return new (Backbone.Paginator.clientPager.extend({
model: model,
paginator_core: {
type: 'GET',
dataType: 'json',
url: '/odata/LibraryFile'
},
paginator_ui: {
// the lowest page index your API allows to be accessed
firstPage: 1,
// which page should the paginator start from
// (also, the actual page the paginator is on)
currentPage: 1,
// how many items per page should be shown
perPage: 2,
// a default number of total pages to query in case the API or
// service you are using does not support providing the total
// number of pages for us.
// 10 as a default in case your service doesn't return the total
totalPages: 5
},
server_api: {
// number of items to return per request/page
'$skip': function () { return this.perPage * (this.currentPage - 1) },
'$top': function () { return this.perPage },
},
parse: function (response) {
console.log(response);
return response.value;
}
}))();
I'm calling the initial fetch like so
myCollection.fetch({
success: function(){
myCollection.pager();
},
silent:true
});
Then, after the user has browsed trough the local pages with the clientPager, he probably wants to load in more pages, without deleting the first pages.
I try to achieve this like this, but for some reason, after i call pager(); the 2 new records are removed.
myCollection.currentPage = 2;
myCollection.fetch({
success: function(){
console.log(myCollection.length) // 4 models, with correct data
myCollection.pager();
console.log(myCollection.length) // the 2 new records are removed
},
silent:true,
remove: false // don't remove old records
});
What am i doing wrong, how can i load it 2 more pages with the Paginator.clientPager ?
I don't want to use requestPager because then i can't do in memory pre-caching, at least, i think.
In my experience, this is caused by the pager() method of Backbone.Paginator.clientPager. You can take a look at the code here:
Backbone.Paginator.clientPager
Lines 292 through to 294 show that the Backbone.Paginator.clientPager.origModels is only assigned to the current models (the one whose length you correctly tested in your illustrations above) if it's undefined. The problem is that by the time the user probably wants to load more pages without deleting the first, the origModels property would already be set as a result of the initial fetch.
This means you'd have to explicitly make origModels undefined again before pager() would act as you want. Note what happens later on line 296 of the source code (models is assigned to a copy of origModels). That's why your two new records were removed. The following code should work as you intended:
myCollection.currentPage = 2;
myCollection.fetch({
success: function(){
delete myCollection.origModels; // to ensure that origModels is overridden in pager() call below
myCollection.pager();
},
silent:true,
remove: false // don't remove old records
});

Categories

Resources