Calling multiple Ajax functions in conjunction with SetInterval - javascript

I have a set of printers associated with different devices. Every 20 seconds I check the status of the printers and display their status (offline, online, out of paper, etc.). User can select a device from a "Devices" dropdown and get status of printers associated with that device; the default on page load is "all devices".
So, there are two parts to getting status: get list of printers for selected device; get status for that list of printers.
To do this I use setInterval function within which I call an Ajax function to get the status.
I am having trouble getting two ajax functions (get device's printers and get printers' status) working in conjunction with setInterval. Getting the list of printers needs to be done once (or until device is changed), getting status needs to be done every 20 seconds.
I think using promise is the way to do it (I could be wrong) but it doesn't work properly. I need some expert assistance.
This is what I have tried but it seems both ajax functions are executed every 20 seconds.
var statusParameters;
var printers = [];
var mpeName;
var v;
var pm;
function printer(idn, hostName, ipAddress) {
this.IDN = idn;
this.HostName = hostName;
this.IPAddress = ipAddress;
}
$(document).ready(function () {
statusParameters = {
interval: 20000,
interval_id: 0,
intervalDetail_id: 0,
};
...
mpeName = ''; // denotes all printers; when user selects a device this value changes
fetchStatusData();
statusParameters.interval_id = setInterval(function () {
fetchStatusData()
}, statusParameters.interval);
// Get list of printers for selected device
pm =
$.ajax({
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
url: 'Services/ps.asmx/GetPrinterMappingCfg',
cache: false,
data: JSON.stringify({ MPEName: mpeName }),
}).done(function (result) {
jResult = JSON.parse(result.d);
$.each(jResult, function (index, value) {
var p = new printer(value.IDN, value.Hostname, value.IPAddress);
printers.push(p);
});
}).fail(function (jqXHR, textStatus, errorThrown) {
alert(textStatus + ' - ' + errorThrown + '\n' + jqXHR.responseText);
});
})
function fetchStatusData() {
// I tried to put the above "pm" right here too
$.when(pm)
.done(function (r1) {
$.each(printers, function (index, value) {
var currPrinter = value;
$.ajax({
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
url: "Services/ps.asmx/GetPrinterStatus",
cache: false,
//data: "",
data: JSON.stringify({ PrinterIPAddress: currPrinter.IPAddress }),
}).done(function (result) {
// initial display or updating of status info
}).fail(function (jqXHR, textStatus, errorThrown) {debugger
...
});
});
printers.length = 0; // because every 20 sec. it retrieves printer list!
}).fail(function (jqXHR, textStatus, errorThrown) {debugger
...
});
The problem I am trying to solve is I want the retrieving of list of printers to be done once, or until user selects a different device not every 20 seconds. It is a waste to keep getting the same printer list every 20 seconds.
Also, the way it is now, on initial page load it does not display printers and their status but will after 20 seconds. It will print on initial load if I move "pm" inside of "fetchStatusData" function.
Update
I think I might not have explained what I am trying to do properly. Basically, this is what I am after:
Given list of devices in a dropdown list, with "All Devices" selected on page load
Get list of printers for selected device from dropdown
Repeat the following every 20 seconds
Get status of each printer in list of printers
When user selects a new device, get list of printers again
I was thinking another way might be to create a array of "device" objects, each having an array of printer objects in addition to other properties like DeviceID, etc.
This is done only once on document.ready(). Then when a new device is selected, I already have the list of printers and can get it that way. Still would get stuck in setInterval portion of it.

Related

Problems with Instagram API on followers count

I am currently running a script to have a live count of followers but it randomly stops working for a while and when I refresh the page, the number drops to 0 until I refresh it again randomly. Not sure what I am doing wrong, is there maybe a way to get the count of followers without going through an API?
EDIT: Actually found out why. The script is making too many requests so it passes the limits set by IG, is there another way to pull the amount of followers? Or limit the requests sent by the script?
Here is the code I use to pull the number from the API
var myCounter = new flipCounter('flip-counter', {value:0,auto:false});
var token = 'ACCESS_TOKEN';
var ref = false;
var tt;
function refs(){
$.ajax({
url: 'https://api.instagram.com/v1/users/self',
dataType: 'jsonp',
type: 'GET',
data: {access_token: token},
success: function(data){
var follows = data['data']['counts']['followed_by'];
if(!ref){
myCounter.incrementTo(follows, 3, 100);
ref=true;
}else{
myCounter.setValue(follows);
}
clearTimeout(tt);
tt=setTimeout(function(){
refs();
},3000);
},
error: function(data){
console.log(data);
}
});
}
refs();
</script>

JQuery AJAX call calls URI multiple times, scales with call

I have an web page I am creating to display information from a database, the page displays 2 tables, one pending table and one history table. The history table is automatically set to the current day's date. So when someone wants to change the date range to see the history, they change the date using a calendar date picker set up in JavaScript.
In this same file, I have an AJAX call that posts the new date filters. The first time it is clicked while on the page, it makes one call, then the second it makes 2 calls, the third it makes 4 calls, and so on making 2^n calls where n is the click number before refreshing the page.
This also happens with the other AJAX call I have happen which is to update the pending table automatically every 6 seconds.
This image is what the network calls look like when running. The code for this call is:
$(document).ready(function() {
//Enable date picker for id startDate
$("#startDate").datepicker();
//Enable date picker for id endDate
$("#endDate").datepicker();
//Set the datepickers to read only so only the calendar can be used to select a date
$("#startDate").attr({
readOnly: false,
style: "background-color:#FFFFFF"
});
$("#endDate").attr({
readOnly: false,
style: "background-color:#FFFFFF"
});
// update function to update pending table
var update = function() {
$.ajax({
url: "pending",
type: "GET",
dataType: "html",
success: function(data) {
//Replace existing table with data returned from query
$('#pendTable').html(data);
move();
},
error: function(xhr, ajaxOptions, thrownError) {
alert(xhr.status);
alert(thrownError);
window.location.href = "";
}
});
};
// automatically updates the pending table every 6 minutes
setInterval(update, 360000);
//On filter change, submit the filters and update the table div
$('.filter').on('change', function() {
var filterValue = $(this).val(),
startDate = document.getElementById('startDate').value,
endDate = document.getElementById('endDate').value;
$.ajax({
url: "postFilters",
async: false,
type: "POST",
data: $('#filters').serialize(),
dataType: "html",
success: function(data) {
//Replace existing table with data returned from query
$('#histTable').html(data);
},
error: function(xhr, ajaxOptions, thrownError) {
alert(xhr.status);
alert(thrownError);
window.location.href = "";
}
});
});
});
Also on my console it shoes that the call is being made multiple times , I have log inside the controllers to notify me when they are called and they are the same number of times it shows up on the network logs of Chrome.
What is wrong with this? I cannot figure it out.

"Long Polling" simulation holding up entire web page

Brief Overview
I have a turn-based web app that puts a 60 second limit per turn, unless they end their turn before 60 seconds, whereby the next user's turn begins.
It works by preventing the production of data on the PHP page by way of a while statement which checks for new data, produces it if it exists, or sleeps and resets if it doesn't:
while($olddata === $newdata){
sleep(2);
/* get new data and repeat */
}
I got this concept from these StackOverflow questions:
How do I implement basic "Long Polling"?
Ajax push system
Issue
However, once the callout begins, the page becomes relatively unresponsive; doing something simple such as refreshing the page will not work until the timeout is complete or new data is received.
How can I configure this code so that the page remains responsive while awaiting new data?
AJAX/jQuery code
function draftPing(){
//This $holder element holds the data including the
//row ID, which is used to determine which turn number
//we are on
var $holder = $("#data-holder");
var currID = $holder.attr("data-currID");
$.ajax({
type: "POST",
url: "../inc/draft-ping.php",
data: { currID : currID },
async: true,
cache: false,
timeout: 60000,
success: function(data) {
var jsonData = $.parseJSON(data);
//Update $holder with new turn ID
$holder.attr("data-currID", jsonData[0]);
/* Do stuff with data */
updateDeadline(jsonData[1]);
updateTeam(jsonData[3]);
updateDraft(jsonData[4]);
/* Begin the next call for new information (wait 1s)*/
setTimeout(
draftPing,
1000
);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert("Draft retrieve error: ", textStatus + " (" + errorThrown + ")");
setTimeout(
draftPing, /* Try again after 5s*/
5000);
}
});
}
PHP Code
<?php
session_start();
require_once("../config.php");
require_once("classes.php");
require_once("functions.php");
$postedID = $_POST["currID"];
$draft = new Draft($user->getLeagueID());
$currID = $draft->getCurrDraftRow();
//This is the "long polling" simulation...
//the AJAX callback won't produce any information
//until the current ID is different to the ID
//on the page with the AJAX post function
while($currID == $postedID){
sleep(2);
$currID = $draft->getCurrDraftRow();
}
/* Get all the data - redacted because it's not important (and it works) */
//Output all the data as one JSON object
exit(json_encode(array($nid, $ndeadline, $nuserid, $fteam, $fdraft)));
If you opened a session with session_start() better close it with session_write_close() before you start waiting, or access to the session will be blocked in all other requests.
<?php
session_start();
require_once("../config.php");
require_once("classes.php");
require_once("functions.php");
$postedID = $_POST["currID"];
$draft = new Draft($user->getLeagueID());
$currID = $draft->getCurrDraftRow();
//This is the "long polling" simulation...
//the AJAX callback won't produce any information
//until the current ID is different to the ID
//on the page with the AJAX post function
while($currID == $postedID){
session_write_close(); //added
sleep(2);
session_start(); //if needed, doesn't look like it is though
$currID = $draft->getCurrDraftRow();
}
/* Get all the data - redacted because it's not important (and it works) */
//Output all the data as one JSON object
exit(json_encode(array($nid, $ndeadline, $nuserid, $fteam, $fdraft)));

Dynamic html elements show only when going through debugger

I'm working on project that simulates Twitter and I'm using HTML + JS on client and WCF services on server side (ajax calls), and Neo4J as database.
For example:
in $(document).ready(function ()
there is DisplayTweets service call -> DisplayTweets(username)
function DisplayTweets(userName) {
$.ajax(
{
type: "GET", //GET or POST or PUT or DELETE verb
url: "Service.svc/DisplayTweets", // Location of the service
data: { userName: userName },
contentType: "application/json; charset=utf-8", // content type sent to server
dataType: "json",
processdata: true, //True or False
success: function (msg) //On Successfull service call
{
DisplayTweetsSucceeded(msg);
},
error: function () // When Service call fails
{
alert("DISPLAY TWEETS ERROR");
}
}
);
}
and then DisplayTweetsSucceeded(msg) where msg would be json array of users tweets
function DisplayTweetsSucceeded(result)
{
for (var i = 0; i < result.length; i++)
{
var tweet = JSON.parse(result[i]);
var id_tweet = tweet.id;
var content_tweet = tweet.content;
var r_count_tweet = tweet.r_count;
NewTweet(null, id_tweet, content_tweet, r_count_tweet);
}
}
Function NewTweet is used for dynamic generating of tweets.
Problem is when I first load html page, nothing shows up, neither when I load it multiple times again. It only shows when I go through Firebug, line by line.
I'm presuming that maybe getting data from database is slower, but I'm not sure and also have no idea how to solve this. Any help will be very much appreciated, thank you in advance!

Show popup/alert if account has related entity records

I have created a custom entity called Alert. I have associated this with the out of the box Account entity.
What I want to do now is to customise the Account form so that when a user opens it, it checks if the current account has any active alerts. If it does, it should show a message informing them of this (a javascript alert?) and then navigate to the alerts view for the account.
I've done some basic javascript in CRM but I'm not sure how to query related entities.
Note Active alert is defined by the Display From and Display Until dates in the Alert being active dates (Display From <= Today AND Display Until >= Today).
Update
Thanks for pointing me in the direction of oData. I now have the following function which is looking up the account set but expanding the relationship with the alerts. I'm trying to figure out how to check if there are any alerts, currently my code always triggers the javascript alert.
function CheckForAlerts(accountId)
{
var odataSelect = "http://mscrmdev/Test/xrmservices/2011/OrganizationData.svc/AccountSet?$expand=new_account_new_alert_Account&$filter=AccountNumber eq '" + accountId + "'";
$.ajax({
type: "GET",
contentType: "application/json; charset=utf-8",
datatype: "json",
url: odataSelect,
beforeSend: function (XMLHttpRequest) { XMLHttpRequest.setRequestHeader("Accept", "application/json"); },
success: function (data, textStatus, XmlHttpRequest)
{
// Use only one of these two methods
// Use for a selection that may return multiple entities
ProcessReturnedEntities(data.d.results);
},
error: function (XmlHttpRequest, textStatus, errorThrown) { alert('OData Select Failed: ' + odataSelect); }
});
}
function ProcessReturnedEntities(ManyEntities)
{
var oneEntity = ManyEntities[0];
if (oneEntity != null)
{
alert('There are active alerts associated with this account.');
}
}
The best way to do this will be via an oData query from the javascript. The CRM 2011 SDK comes with some helper functions for oData calls like this. You will want to use the 'retrieveMultiple' method which will allow you to retrieve all 'alerts' with a lookup to the 'account' in question.
First add the 'RESTJQueryEditor.js' file from the SDK to your form and then you can add your own custom script to perform the retrieve. I then suggest creating the message which you wish to show the user in the callback success function, something like the following:-
retrieveMultiple('nameOfYourAlertEntitySet', '?$filter=myAccountLookupName eq ' + accountId, function(alerts){
if(alerts.length > 0)
{
var message = '';
for(var index = 0; index<alerts.length; index++)
{
message += 'alert: ' + alerts[index].name;
}
alert('Found associated alerts: ' + message);
}
else
{
alert('No associated alerts found for this account');
}
},
function(){
// Log an exception
});
You will want to make the alert message a little nicer of course and adjust your attribute names accordingly, but this is the flavour of what you want to do I believe. Additionally, you can add any further criteria on the alert entity in the filter by use of the 'and' keyword.
Let me know if you have any issues.

Categories