dojo.cookie(id) not able to look up cookie by id intermittently - javascript

_setPrintExportCookieInterval: function(/**String*/requestId, /**function*/closePopup) {
//have the interval autoexpire after some amount of seconds
var count = 0;
var intervalMs = 2000;
var intervalId = self.setInterval(function() {
var reportCookie = dojo.cookie(requestId);
console.debug('requestId ' + requestId);
if(reportCookie || count > 300000) { //5 mins
//if there's a status failure, don't close the window
console.debug('reportCookie ' + reportCookie);
if(reportCookie == undefined){
console.debug("print/export request returned with undefined status ");
} else if(reportCookie == "success") {
closePopup();
} else{
console.debug("print/export request returned with nonstandard status " + reportCookie);
}
window.clearInterval(intervalId);
//delete the cookie
dojo.cookie(requestId, null, {path: "/", expires: -1});
//destroy the iframe
//dojo.destroy(dojo.byId(requestId));
};
count+=intervalMs;
}, intervalMs);
return intervalId;
},
I'm having problems with the above javascript function. The problem generally is that sometimes:
var reportCookie = dojo.cookie(requestId);
returns null, but when I look in my browser's debugging tool I'm able to see that the cookie exists with a value of success. This happens one in every 10 times this function is called. Any ideas why dojo.cookie() is not able to look up the cookie by ID only some of the time?

Make sure that you specify the path when you are retrieving the cookie, otherwise it defaults to the current location. This will allow you to get the Cookie from any path within your domain.
dojo.cookie(requestId, null, {path: "/" });

Related

Use javascript to determine if last page visited was my site

I am trying to show a popup on mobile devices, only when the user has first visited a page on my web site. I tried doing this with document.referrer, similar to this. But it does not appear to work on the production site due to it using SSL.
Should I set a cookie when the visitor first comes to the site? Then check for it on subsequent visits? Any ideas? The end result is I need to set a config variable in the popup's javascript config, so that showonmobile: true or false.
I ended up using a cookie to solve this and it is working well:
function setCookie(key, value, expiry) {
var expires = new Date();
expires.setTime(expires.getTime() + (expiry * 60 * 60 * 1000));
document.cookie = key + '=' + value + ';expires=' + expires.toUTCString();
}
function getCookie(key) {
var keyValue = document.cookie.match('(^|;) ?' + key + '=([^;]*)(;|$)');
return keyValue ? keyValue[2] : null;
}
function onSiteAlready() {
if (getCookie('onSite') == 'true') {
return true;
}
else {
setCookie('onSite', 'true', 1)
return false;
}
}
// popup code
showOnMobile: onSiteAlready()

How do I run a function once session storage is != undefined

I am in a situation wherein I have a an external JavaScript file that makes an ajax call and saves certain data to session storage. The JavaScript file loads from an external site and therefore, I cannot edit it.
I need to run a function to consume the saved data as soon as it loads into session storage. How can I trigger a function once this data loads?
Maybe this can help you:
window.onstorage = function(e) {
console.log('The ' + e.key + ' key has been changed from ' + e.oldValue + ' to ' + e.newValue + '.');
};
More info here and here
So you could subscribe to your session key changes with (not tested):
window.onstorage = function(e) {
if (
e.storageArea === sessionStorage &&
e.key === "<your_key>" &&
e.oldValue === undefined &&
e.newValue !== undefined
) {
console.log("my key is not undefined anymore")
}
};
UPDATE: So it seems that it is not working for you. Then you can try something like this (using interval to check if sessionStorage changes):
var INTERVAL = 2000;
// Then, in your code you can check every `INTERVAL` milleconds
// if the sessionKey you need is not null
console.log("Program starts");
// You can limit your intents too
var limit = 5;
var intervalId = setInterval(function() {
console.log("Checking sessionStorage");
var test = sessionStorage.getItem("test");
if (test !== null) {
console.log("'test' is now defined: " + test);
clearInterval(intervalId);
}
if (--limit <= 0) {
console.log("'test' has not changed");
clearInterval(intervalId);
}
}, INTERVAL);
Test here: https://jsbin.com/tukubutoje/edit?js,console
See StorageEvent:
A StorageEvent is sent to a window when a storage area it has access to is changed within the context of another document.
For example:
window.addEventListener('storage', function(e) {
document.querySelector('.my-key').textContent = e.key;
document.querySelector('.my-old').textContent = e.oldValue;
document.querySelector('.my-new').textContent = e.newValue;
document.querySelector('.my-url').textContent = e.url;
document.querySelector('.my-storage').textContent = e.storageArea;
});
Here we add an event listener to the window object that fires when the Storage object associated with the current origin is changed. As you can see above, the event object associated with this event has a number of properties containing useful information — the key of the data that changed, the old value before the change, the new value after that change, the URL of the document that changed the storage, and the storage object itself.

Execute javascript (PhantomJS) after load full webpage [duplicate]

I'm using PhantomJS v1.4.1 to load some web pages. I don't have access to their server-side, I just getting links pointing to them. I'm using obsolete version of Phantom because I need to support Adobe Flash on that web pages.
The problem is many web-sites are loading their minor content async and that's why Phantom's onLoadFinished callback (analogue for onLoad in HTML) fired too early when not everything still has loaded. Can anyone suggest how can I wait for full load of a webpage to make, for example, a screenshot with all dynamic content like ads?
Another approach is to just ask PhantomJS to wait for a bit after the page has loaded before doing the render, as per the regular rasterize.js example, but with a longer timeout to allow the JavaScript to finish loading additional resources:
page.open(address, function (status) {
if (status !== 'success') {
console.log('Unable to load the address!');
phantom.exit();
} else {
window.setTimeout(function () {
page.render(output);
phantom.exit();
}, 1000); // Change timeout as required to allow sufficient time
}
});
I would rather periodically check for document.readyState status (https://developer.mozilla.org/en-US/docs/Web/API/document.readyState). Although this approach is a bit clunky, you can be sure that inside onPageReady function you are using fully loaded document.
var page = require("webpage").create(),
url = "http://example.com/index.html";
function onPageReady() {
var htmlContent = page.evaluate(function () {
return document.documentElement.outerHTML;
});
console.log(htmlContent);
phantom.exit();
}
page.open(url, function (status) {
function checkReadyState() {
setTimeout(function () {
var readyState = page.evaluate(function () {
return document.readyState;
});
if ("complete" === readyState) {
onPageReady();
} else {
checkReadyState();
}
});
}
checkReadyState();
});
Additional explanation:
Using nested setTimeout instead of setInterval prevents checkReadyState from "overlapping" and race conditions when its execution is prolonged for some random reasons. setTimeout has a default delay of 4ms (https://stackoverflow.com/a/3580085/1011156) so active polling will not drastically affect program performance.
document.readyState === "complete" means that document is completely loaded with all resources (https://html.spec.whatwg.org/multipage/dom.html#current-document-readiness).
EDIT 2022:
I created this response 8 years ago and I did not use PhantomJS since then. It is very probable it won't work now in some cases. Also now I think it is not possible to create a one-size-fits-all solution to be absolutely sure the page is loaded. This is because some pages may load additional resources after document is ready. For example, there might be some JS code on the website that waits for the document to be ready an then loads some additional assets (after document state changes to ready) - in this case the onPageReady will trigger and after that the page will start loading some more resources again.
I still think the above snipped is a good starting point and may work in most cases, but may also necessary to create a specific solutions to handle specific websites.
You could try a combination of the waitfor and rasterize examples:
/**
* See https://github.com/ariya/phantomjs/blob/master/examples/waitfor.js
*
* Wait until the test condition is true or a timeout occurs. Useful for waiting
* on a server response or for a ui change (fadeIn, etc.) to occur.
*
* #param testFx javascript condition that evaluates to a boolean,
* it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or
* as a callback function.
* #param onReady what to do when testFx condition is fulfilled,
* it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or
* as a callback function.
* #param timeOutMillis the max amount of time to wait. If not specified, 3 sec is used.
*/
function waitFor(testFx, onReady, timeOutMillis) {
var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 3000, //< Default Max Timout is 3s
start = new Date().getTime(),
condition = (typeof(testFx) === "string" ? eval(testFx) : testFx()), //< defensive code
interval = setInterval(function() {
if ( (new Date().getTime() - start < maxtimeOutMillis) && !condition ) {
// If not time-out yet and condition not yet fulfilled
condition = (typeof(testFx) === "string" ? eval(testFx) : testFx()); //< defensive code
} else {
if(!condition) {
// If condition still not fulfilled (timeout but condition is 'false')
console.log("'waitFor()' timeout");
phantom.exit(1);
} else {
// Condition fulfilled (timeout and/or condition is 'true')
console.log("'waitFor()' finished in " + (new Date().getTime() - start) + "ms.");
typeof(onReady) === "string" ? eval(onReady) : onReady(); //< Do what it's supposed to do once the condition is fulfilled
clearInterval(interval); //< Stop this interval
}
}
}, 250); //< repeat check every 250ms
};
var page = require('webpage').create(), system = require('system'), address, output, size;
if (system.args.length < 3 || system.args.length > 5) {
console.log('Usage: rasterize.js URL filename [paperwidth*paperheight|paperformat] [zoom]');
console.log(' paper (pdf output) examples: "5in*7.5in", "10cm*20cm", "A4", "Letter"');
phantom.exit(1);
} else {
address = system.args[1];
output = system.args[2];
if (system.args.length > 3 && system.args[2].substr(-4) === ".pdf") {
size = system.args[3].split('*');
page.paperSize = size.length === 2 ? {
width : size[0],
height : size[1],
margin : '0px'
} : {
format : system.args[3],
orientation : 'portrait',
margin : {
left : "5mm",
top : "8mm",
right : "5mm",
bottom : "9mm"
}
};
}
if (system.args.length > 4) {
page.zoomFactor = system.args[4];
}
var resources = [];
page.onResourceRequested = function(request) {
resources[request.id] = request.stage;
};
page.onResourceReceived = function(response) {
resources[response.id] = response.stage;
};
page.open(address, function(status) {
if (status !== 'success') {
console.log('Unable to load the address!');
phantom.exit();
} else {
waitFor(function() {
// Check in the page if a specific element is now visible
for ( var i = 1; i < resources.length; ++i) {
if (resources[i] != 'end') {
return false;
}
}
return true;
}, function() {
page.render(output);
phantom.exit();
}, 10000);
}
});
}
Here is a solution that waits for all resource requests to complete. Once complete it will log the page content to the console and generate a screenshot of the rendered page.
Although this solution can serve as a good starting point, I have observed it fail so it's definitely not a complete solution!
I didn't have much luck using document.readyState.
I was influenced by the waitfor.js example found on the phantomjs examples page.
var system = require('system');
var webPage = require('webpage');
var page = webPage.create();
var url = system.args[1];
page.viewportSize = {
width: 1280,
height: 720
};
var requestsArray = [];
page.onResourceRequested = function(requestData, networkRequest) {
requestsArray.push(requestData.id);
};
page.onResourceReceived = function(response) {
var index = requestsArray.indexOf(response.id);
if (index > -1 && response.stage === 'end') {
requestsArray.splice(index, 1);
}
};
page.open(url, function(status) {
var interval = setInterval(function () {
if (requestsArray.length === 0) {
clearInterval(interval);
var content = page.content;
console.log(content);
page.render('yourLoadedPage.png');
phantom.exit();
}
}, 500);
});
Maybe you can use the onResourceRequested and onResourceReceived callbacks to detect asynchronous loading. Here's an example of using those callbacks from their documentation:
var page = require('webpage').create();
page.onResourceRequested = function (request) {
console.log('Request ' + JSON.stringify(request, undefined, 4));
};
page.onResourceReceived = function (response) {
console.log('Receive ' + JSON.stringify(response, undefined, 4));
};
page.open(url);
Also, you can look at examples/netsniff.js for a working example.
In my program, I use some logic to judge if it was onload: watching it's network request, if there was no new request on past 200ms, I treat it onload.
Use this, after onLoadFinish().
function onLoadComplete(page, callback){
var waiting = []; // request id
var interval = 200; //ms time waiting new request
var timer = setTimeout( timeout, interval);
var max_retry = 3; //
var counter_retry = 0;
function timeout(){
if(waiting.length && counter_retry < max_retry){
timer = setTimeout( timeout, interval);
counter_retry++;
return;
}else{
try{
callback(null, page);
}catch(e){}
}
}
//for debug, log time cost
var tlogger = {};
bindEvent(page, 'request', function(req){
waiting.push(req.id);
});
bindEvent(page, 'receive', function (res) {
var cT = res.contentType;
if(!cT){
console.log('[contentType] ', cT, ' [url] ', res.url);
}
if(!cT) return remove(res.id);
if(cT.indexOf('application') * cT.indexOf('text') != 0) return remove(res.id);
if (res.stage === 'start') {
console.log('!!received start: ', res.id);
//console.log( JSON.stringify(res) );
tlogger[res.id] = new Date();
}else if (res.stage === 'end') {
console.log('!!received end: ', res.id, (new Date() - tlogger[res.id]) );
//console.log( JSON.stringify(res) );
remove(res.id);
clearTimeout(timer);
timer = setTimeout(timeout, interval);
}
});
bindEvent(page, 'error', function(err){
remove(err.id);
if(waiting.length === 0){
counter_retry = 0;
}
});
function remove(id){
var i = waiting.indexOf( id );
if(i < 0){
return;
}else{
waiting.splice(i,1);
}
}
function bindEvent(page, evt, cb){
switch(evt){
case 'request':
page.onResourceRequested = cb;
break;
case 'receive':
page.onResourceReceived = cb;
break;
case 'error':
page.onResourceError = cb;
break;
case 'timeout':
page.onResourceTimeout = cb;
break;
}
}
}
I found this approach useful in some cases:
page.onConsoleMessage(function(msg) {
// do something e.g. page.render
});
Than if you own the page put some script inside:
<script>
window.onload = function(){
console.log('page loaded');
}
</script>
I found this solution useful in a NodeJS app.
I use it just in desperate cases because it launches a timeout in order to wait for the full page load.
The second argument is the callback function which is going to be called once the response is ready.
phantom = require('phantom');
var fullLoad = function(anUrl, callbackDone) {
phantom.create(function (ph) {
ph.createPage(function (page) {
page.open(anUrl, function (status) {
if (status !== 'success') {
console.error("pahtom: error opening " + anUrl, status);
ph.exit();
} else {
// timeOut
global.setTimeout(function () {
page.evaluate(function () {
return document.documentElement.innerHTML;
}, function (result) {
ph.exit(); // EXTREMLY IMPORTANT
callbackDone(result); // callback
});
}, 5000);
}
});
});
});
}
var callback = function(htmlBody) {
// do smth with the htmlBody
}
fullLoad('your/url/', callback);
This is an implementation of Supr's answer. Also it uses setTimeout instead of setInterval as Mateusz Charytoniuk suggested.
Phantomjs will exit in 1000ms when there isn't any request or response.
// load the module
var webpage = require('webpage');
// get timestamp
function getTimestamp(){
// or use Date.now()
return new Date().getTime();
}
var lastTimestamp = getTimestamp();
var page = webpage.create();
page.onResourceRequested = function(request) {
// update the timestamp when there is a request
lastTimestamp = getTimestamp();
};
page.onResourceReceived = function(response) {
// update the timestamp when there is a response
lastTimestamp = getTimestamp();
};
page.open(html, function(status) {
if (status !== 'success') {
// exit if it fails to load the page
phantom.exit(1);
}
else{
// do something here
}
});
function checkReadyState() {
setTimeout(function () {
var curentTimestamp = getTimestamp();
if(curentTimestamp-lastTimestamp>1000){
// exit if there isn't request or response in 1000ms
phantom.exit();
}
else{
checkReadyState();
}
}, 100);
}
checkReadyState();
This the code I use:
var system = require('system');
var page = require('webpage').create();
page.open('http://....', function(){
console.log(page.content);
var k = 0;
var loop = setInterval(function(){
var qrcode = page.evaluate(function(s) {
return document.querySelector(s).src;
}, '.qrcode img');
k++;
if (qrcode){
console.log('dataURI:', qrcode);
clearInterval(loop);
phantom.exit();
}
if (k === 50) phantom.exit(); // 10 sec timeout
}, 200);
});
Basically given the fact you're supposed to know that the page is full downloaded when a given element appears on the DOM. So the script is going to wait until this happens.
I use a personnal blend of the phantomjs waitfor.js example.
This is my main.js file:
'use strict';
var wasSuccessful = phantom.injectJs('./lib/waitFor.js');
var page = require('webpage').create();
page.open('http://foo.com', function(status) {
if (status === 'success') {
page.includeJs('https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js', function() {
waitFor(function() {
return page.evaluate(function() {
if ('complete' === document.readyState) {
return true;
}
return false;
});
}, function() {
var fooText = page.evaluate(function() {
return $('#foo').text();
});
phantom.exit();
});
});
} else {
console.log('error');
phantom.exit(1);
}
});
And the lib/waitFor.js file (which is just a copy and paste of the waifFor() function from the phantomjs waitfor.js example):
function waitFor(testFx, onReady, timeOutMillis) {
var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 3000, //< Default Max Timout is 3s
start = new Date().getTime(),
condition = false,
interval = setInterval(function() {
if ( (new Date().getTime() - start < maxtimeOutMillis) && !condition ) {
// If not time-out yet and condition not yet fulfilled
condition = (typeof(testFx) === "string" ? eval(testFx) : testFx()); //< defensive code
} else {
if(!condition) {
// If condition still not fulfilled (timeout but condition is 'false')
console.log("'waitFor()' timeout");
phantom.exit(1);
} else {
// Condition fulfilled (timeout and/or condition is 'true')
// console.log("'waitFor()' finished in " + (new Date().getTime() - start) + "ms.");
typeof(onReady) === "string" ? eval(onReady) : onReady(); //< Do what it's supposed to do once the condi>
clearInterval(interval); //< Stop this interval
}
}
}, 250); //< repeat check every 250ms
}
This method is not asynchronous but at least am I assured that all the resources were loaded before I try using them.
This is an old question, but since I was looking for full page load but for Spookyjs (that uses casperjs and phantomjs) and didn't find my solution, I made my own script for that, with the same approach as the user deemstone .
What this approach does is, for a given quantity of time, if the page did not receive or started any request it will end the execution.
On casper.js file (if you installed it globally, the path would be something like /usr/local/lib/node_modules/casperjs/modules/casper.js) add the following lines:
At the top of the file with all the global vars:
var waitResponseInterval = 500
var reqResInterval = null
var reqResFinished = false
var resetTimeout = function() {}
Then inside function "createPage(casper)" just after "var page = require('webpage').create();" add the following code:
resetTimeout = function() {
if(reqResInterval)
clearTimeout(reqResInterval)
reqResInterval = setTimeout(function(){
reqResFinished = true
page.onLoadFinished("success")
},waitResponseInterval)
}
resetTimeout()
Then inside "page.onResourceReceived = function onResourceReceived(resource) {" on the first line add:
resetTimeout()
Do the same for "page.onResourceRequested = function onResourceRequested(requestData, request) {"
Finally, on "page.onLoadFinished = function onLoadFinished(status) {" on the first line add:
if(!reqResFinished)
{
return
}
reqResFinished = false
And that's it, hope this one helps someone in trouble like I was. This solution is for casperjs but works directly for Spooky.
Good luck !
this is my solution its worked for me .
page.onConsoleMessage = function(msg, lineNum, sourceId) {
if(msg=='hey lets take screenshot')
{
window.setInterval(function(){
try
{
var sta= page.evaluateJavaScript("function(){ return jQuery.active;}");
if(sta == 0)
{
window.setTimeout(function(){
page.render('test.png');
clearInterval();
phantom.exit();
},1000);
}
}
catch(error)
{
console.log(error);
phantom.exit(1);
}
},1000);
}
};
page.open(address, function (status) {
if (status !== "success") {
console.log('Unable to load url');
phantom.exit();
} else {
page.setContent(page.content.replace('</body>','<script>window.onload = function(){console.log(\'hey lets take screenshot\');}</script></body>'), address);
}
});
Do Mouse move while page is loading should work.
page.sendEvent('click',200, 660);
do { phantom.page.sendEvent('mousemove'); } while (page.loading);
UPDATE
When submitting the form, nothing was returned, so the program stopped. The program did not wait for the page to load as it took a few seconds for the redirect to begin.
telling it to move the mouse until the URL changes to the home page gave the browser as much time as it needed to change. then telling it to wait for the page to finish loading allowed the page to full load before the content was grabbed.
page.evaluate(function () {
document.getElementsByClassName('btn btn-primary btn-block')[0].click();
});
do { phantom.page.sendEvent('mousemove'); } while (page.evaluate(function()
{
return document.location != "https://www.bestwaywholesale.co.uk/";
}));
do { phantom.page.sendEvent('mousemove'); } while (page.loading);

How do I get the gender from a particular user when updating a different table? Azure mobile services

I have a table called Subscription and another table called Client I need the gender of the Client who owns the subscription every time I make an update. Here's my update script:
function update(item, user, request) {
var subscriptionId = item.id;
var subscriptionActivitiesTable = tables.getTable("SubscriptionActivity");
var userTable = tables.getTable("User");
var activityTable = tables.getTable("Activity");
var userGender = userTable.where({id: item.UserId}).select('Gender').take(1).read();
console.log(userGender);
activityTable.where({PlanId:item.PlanId, Difficulty: item.Difficulty}).read({
success: function(results){
var startDate = item.StartDate;
results.forEach(function(activity)
{
var testDate = new Date(startDate.getFullYear(),startDate.getMonth(), startDate.getDate());
testDate.setDate(testDate.getDate() + activity.Sequence + (activity.Week*7));
subscriptionActivitiesTable.insert({SubscriptionId: subscriptionId,
ActivityId: activity.id, ShowDate: new Date(testDate.getFullYear(),
testDate.getMonth(), testDate.getDate()), CreationDate: new Date()});
})
}
});
var planWeeks = 12;//VER DE DONDE SACAMOS ESTE NUMERO
var idealWeight = 0;
if (userGender === "Male")
{
idealWeight = (21.7 * Math.pow(parseInt(item.Height)/100,2));
}
else
{
idealWeight = (23 * Math.pow(parseInt(item.Height)/100,2));
}
var metabolismoBasal = idealWeight * 0.95 * 24;
var ADE = 0.1 * metabolismoBasal;
var activityFactor;
if (item.Difficulty === "Easy")
{
activityFactor = 1.25;
}
else if(item.Difficulty === "Medium")
{
activityFactor = 1.5;
}
else
{
activityFactor = 1.75;
}
var caloricRequirement = ((metabolismoBasal + ADE)*activityFactor);
activityTable.where(function(item, caloricRequirement){
return this.PlanId === item.PlanId && this.Type != "Sport" &&
this.CaloricRequirementMin <= caloricRequirement &&
this.CaloricRequirementMax >= caloricRequirement;}, item, caloricRequirement).read({
success: function(results)
{
var startDate = item.StartDate;
results.forEach(function(activity)
{
for (var i=0;i<planWeeks;i++)
{
var testDate = new Date(startDate.getFullYear(),startDate.getMonth(), startDate.getDate());
testDate.setDate(testDate.getDate() + activity.Sequence + (i*7));
subscriptionActivitiesTable.insert({SubscriptionId: subscriptionId,
ActivityId: activity.id, ShowDate: new Date(testDate.getFullYear(),
testDate.getMonth(), testDate.getDate()), CreationDate: new Date()});
}
})
}
})
request.execute();
}
I tried the code above and clientGender is undefined. As you can see I want to use the gender to set the idealWeight.
The read() method expects a function to be passed in on the success parameter - it doesn't return the result of the query like you'd think.
Try something like this instead:
function update(item, user, request) {
var clientTable = tables.getTable("Client");
var clientGender = 'DEFAULT';
clientTable.where({id: item.ClientId}).select('Gender').take(1).read({
success: function(clients) {
if (clients.length == 0) {
console.error('Unable to find client for id ' + item.ClientId);
} else {
var client = client[0];
clientGender = client.Gender;
// since we're inside the success function, we can continue to
// use the clientGender as it will reflect the correct value
// as retrieved from the database
console.log('INSIDE: ' + clientGender);
}
}
});
// this is going to get called while the clientTable query above is
// still running and will most likely show a value of DEFAULT
console.log('OUTSIDE: ' + clientGender);
}
In this sample, the client table query is kicked off, with a callback function provided in the success parameter. When the query is finished, the callback function is called, and the resulting data is displayed to the log. Meanwhile - while the query is still running, that is - the next statement after the where/take/select/read fluent code is run, another console.log statment is executed to show the value of the clientGender field outside the read function. This code will run while the read statement is still waiting on the database. Your output should look something like this in the WAMS log:
* INSIDE: Male
* OUTSIDE: Default
Since the log shows the oldest entries at the bottom, you can see that the OUTSIDE log entry was written sometime before the INSIDE log.
If you're not used to async or functional programming, this might look weird, but as far as I've found, this is now node works. Functions nested in functions nested in functions can get kind of scary, but if you plan ahead, it probably won't be too bad :-)

How to run a setInterval that loops and tries a max of 10 times before breaking?

I have the following to try to reload on a connection drop:
setInterval(window.location.reload(), 1000);
My concern with this is that it could continue forever, ddos'ing my application.
How can I update the above to try at max 20 times before giving up and breaking?
Thank you
This makes me feel dirty, but you could update/extract the window hash with each refresh:
function hack () {
var last = parseInt(location.hash.slice(1));
if (last < 20) {
window.location.hash = last + 1;
window.location.reload();
}
}
window.location.hash = 0;
setTimeout(hack, 1000);
You need to persist some counter state from one page load to the next so you can know when 20 reloads have been done. Your options are:
A hash value
A query parameter
A cookie value
Something stored in local storage
If you don't need this value to persist beyond just the reloads of this page, then options 1) and 2) are better as they are only as persistent as you need. A hash value will not be sent to your server, but could interfere with other uses of the hash value. A query parameter would be sent to the server, but any reasonable server will ignore query values it doesn't know and it won't interfere with anything else. I'd probably pick a query parameter and have actually used one to avoid infinite redirection loops in some of my code. You could implement option 2) like this:
function checkAutoReload() {
var currentCnt = 0;
var re = /(\?|&)(reloadCnt=)(\d+)/;
var param = window.location.search.match(re), newURL;
if (param) {
currentCnt = parseInt(param[3], 10);
newURL = window.location.href.replace(re, "$1$2" + (currentCnt + 1))
} else {
newURL = window.location.href;
newURL += window.location.search ? "&" : "?";
newURL += "reloadCnt=1";
}
if (currentCnt < 20) {
window.location.replace(newURL);
}
}
setTimeout(checkAutoReload, 1000);
Notice, there's no need for a setInterval() because a given page's code only runs once before it either reloads or finds that it is done reloading.
Store the reloadCount in localStorage
MDN DOM Storage
var maxReload = 20;
var reloadPage = function() {
if (typeof a !== "undefined" && a !== null) {
console.log(localStorage.reloadCount);
localStorage.reloadCount = 0;
};
var reloadCount = parseInt(localStorage.reloadCount, 10);
console.log(reloadCount);
if (reloadCount < maxReload) {
reloadCount += 1;
localStorage.reloadCount = reloadCount;
// RELOAD CODE HERE
};
};
// call reloadPage from your code
reloadPage();

Categories

Resources