How to call function in certain time interval - javascript

I need to run a certain API function, in a certain time period once the access token is granted, and check the status and inform the user if there any changes.
So far i did it by clicking a button on popup window of the firefox addon and calling the functions background js files, so i can receive the info from the API and notify the user. But i need to automate this process in background js files.
Are there any firefox inbuild JS API or any other way to achieve this auto API request calling from addon background files?

Yes, there is, the setInterval() function.
let inter = setInterval(() => {
console.log('HI!');
}, 1000);
To stop the timer, just call: clearInterval(inter);
More info about setInterval() here.

Related

Angular 6: Trying to make synchronous call (delete) on browser close event (beforeunload/unload event of browser)

Actually, I want to update a flag in Db using a service call(Delete method) once the user close the browser. I am able to detect browser close action using onbeforeunload and onunload events but async call doesn't work for me(sometimes in debugging mode it works fine but on higher env it doesn't work).
Then, I tried to make sync request but then I found that Chrome now disallows synchronous XHR during page dismissal when the page is being navigated away from or closed by the user.
check link : https://www.chromestatus.com/feature/4664843055398912
I have tried new XMLHttpRequest() as sync, fetch api also Navigator.sendBeacon() but unfortunately nothing works for me.
Please suggest something which works because I have visited so many posts but nothing works for me.
Thanks in advance.
I have some solution for this. Hope so any one of them solves your issue.
constructor() {
window.onbeforeunload = ()=>{
//call API here
}
}
In your component constructor write above code
OR
In my opinion the better idea is making the heartbeat api that sends requests every N seconds to notify server that the session is active and the user is online. On the server check every M minutes if there was no heartbeat requests for more than N seconds: if it is so - execute the API request(what you wanted to execute on crash).
OR
'beforeunload' would be trigger when refreshing pages, closing tab, or closing the browser.
#HostListener('window:beforeunload', ['$event'])
beforeUnload(e: Event) {
e.returnValue = false;
}
OR
It is not possible to ensure that every time an user exits a browser page a specific function will be triggered. The reason is that the browser could close the window for many reasons. Yes it could be a user action but this is not the only case. For example The browser could crash.
In my case I will have to find another strategy to track the time the user stays on the page. For example I am planning to send a lot of API calls before the user exits with all the informations I need to understand his stay on the page. I will update the answer when I will reach a good solution. Anyway I will still wait for better answers.
You can use the fetch API.
The syntax would be:
fetch('API', {
method: 'POST', // Other opn are also supported like GET,PUT DELETE
body: '',
keepalive: true
});
Just an additional read:
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API

Triggering an Api.ai event through a external server

It is needed to send an alert to the chat after a timer has started.
Scenario:
Remind me to call Bob in 5 minutes
OK, will remind you in 5 minutes
After this dialog fulfillment server will start a timer and when the time goes off, event is to be triggered.
But when using the event api in API.ai will not trigger a message to the chat window which was built using the JS api.
Is there a another way to achieve this.
This is very much possible. In the intents that you setup on API.ai, use #sys.time so that 'call me in 5 minutes' will return a time like 14:05:00. You can use this parameter to start a timer on your JS script and send the message when timer expires.

Isolate setInterval for each thread/user?

I'm using nodejs, and one of the reasons why I switched from a php socket server to nodejs is because of the threading ability. (Essentially, I wanted my monsters in the gameserver to auto attack players).
Let's say in my sever.js file for node I put:
setInterval(function(){
console.log('Hello');
}, 1000);
And I login and authenticate my character on one browser, then look at the console I can see 'Hello' being outputted every second. That's fine, but then I load up a new browser, authenticate another user and then look at the console.. It's actually outputting twice as fast, which is not really the correct way to do this right?
Edit: I'm using https://github.com/websockets/ws and the setInterval function is just under the
socket.on('message', function(Message, flags) {
~~~gameserver authentication /blah mysql blah ~~
setInterval(function(){
console.log('Hello');
}, 1000);
})
Hope this helps, sorry for not being specific enough.
Your script is run for each user (since that is the server). You can listen and emit to a specific user of course. You need to generate an emit for each one, or write the emit in such a way it sends data only to the desired clients.
This may help you: socket.io and node.js to send message to particular client
Edit after comment:
No, the script will be run for each user so you start an interval for each. If you want to start only one you can:
1. Name your interval and if it is defined not start it again.
2. Start the interval on a separate script that you run from console or something like that and it is never accessed by clients.

How to capture visitor time on page

I would like to keep track of how long visitors spend reading a page. If they tab away, or minimize the window, time should not count towards the time on page until they look at the tab again.
I assume some combination of javascript and server side work will be necessary.
A couple of issues I'm struggling with:
What's the best way to store this information in the database?
How do I, with Javascript, capture the time on page with a reasonable degree of accuracy? Do I store events like "page loaded", "user idle", "user returned", "page unloaded", and then separately process all the events in the DB to come up with a time on page?
I've put some work into a small JavaScript library that times how long a user is on a web page. It has the added benefit of more accurately (not perfectly, though) tracking how long a user is actually interacting with the page. It ignores time that a user switches to different tabs, goes idle, minimizes the browser, etc. The Google Analytics method suggested has the shortcoming (as I understand it) that it only checks when a new request is handled by your domain. It compares the previous request time against the new request time, and calls that the 'time spent on your web page'. It doesn't actually know if someone is viewing your page, has minimized the browser, has switched tabs to 3 different web pages since last loading your page, etc.
https://github.com/jasonzissman/TimeMe.js
An example of its usage:
On loading your page:
document.onload = function() {
TimeMe.setIdleDurationInSeconds(30);
TimeMe.setCurrentPageName("my-home-page");
TimeMe.initialize();
}
Retrieving time spent on the page, and sending it to your server when the user leaves your page:
window.onbeforeunload = function (event) {
xmlhttp=new XMLHttpRequest();
xmlhttp.open("POST","ENTER_URL_HERE",false);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
var timeSpentOnPage = TimeMe.getTimeOnCurrentPageInSeconds();
xmlhttp.send(timeSpentOnPage);
};
First, you need to detect when a user has moved away from a tab or is inactive. When this happens, start a timer, when they come back, stop the timer. Counting time with setTimeout/setInterval can be innacurate because of blocking, so I made myself an accurate javascript timer based on the actual difference in datetime: https://gist.github.com/4600726
So your code would look something like this:
timer = new Timer;
window.addEventListener('focus', function() {
timer.start();
}, false);
window.addEventListener('blur', function() {
timer.stop();
// send timer.msecs() to the server maybe??
// if so, also call timer.reset();
}, false);
window.addEventListener('beforeunload', function() {
timer.stop();
// send timer.msecs() to the server via jquery post, or better yet websocket
}, false);
Then you can get the elapsed time with timer.secs(). I guess it depends on your preference how often you want to send info to the server. You could do it on blur.
Another option could be to decree that no mouseover means inactivity. Start the timer and then do a setTimeout, then on the window's mousemove event cancel the setTimeout and start another setTimeout , after which you stop the timer.
As far as sending data to the server, I'd probably opt for sending it on blur and of course beforeunload. My preferred method would be with socket.io since it is fast and always connected, so you could use it to track lots of user events in real time, but you could just to an ajax call to your server. If you just send them as mini user sessions, { user: userId, page: pageId, elapsedTime: msecs } then you could then aggregate the data on the server end when you are doing analysis.

jquery/javascript setInterval

Currently I'm developing a user notification alert message function.
I managed to use setInterval to control my Ajax call (to check if there's any notification msg for the user). But my problem is that I only wanted the notification message only
appear once on the page (Now it displays multiple notification alert msg on the screen). I know that you can use setTimeout to make it only call once but I also needed the page to check if there's a new notification message alert in every 5 min.
Second question is it possible the first round calling the Ajax call instantly and then all other calls every 5 min? Because I wanted the system to check instantly once they logged into the system n then afterward every 5 min.
Here is my code
function getAjaxNotice() {
$.post("/async/getnotification", {},
function(response) {
var notice = $(response);
$("#notices").prepend(notice);
});
return false;
}
setInterval("getAjaxNotice()", 50000);
First of all, you should wrap your initialization code in an onLoad function:
$(document).ready(function() {
// Put all your code here
});
Making it appear once is easy, use .html() instead to set the content rather than add to it:
$("#notices").html(notice);
Third, as a style note, you should not pass a string to setInterval(). Rather, pass a function name:
setInterval( getAjaxNotice, 50000 );
Finally, to make it call the function now, and again after every 5 minutes, use:
// Set the timer
setInterval( getAjaxNotice, 50000 );
// Call it once now
getAjaxNotice();
Also note that 50000 is 50 seconds, not 5 minutes. 5 minutes would be 5 * 60 * 1000 = 300000.
For the first problem, you should be storing the return value from setInterval, and then calling clearInterval(myIntervalId) when you receive an alert.
For the second problem, you can call getAjaxNotice once during onload of the body, and then if no alerts are received, call setInterval at that point.
setInterval's time is in milliseconds.
5 minutes * 60 seconds * 1000 milliseconds = 300000ms
Also, I suggest you pass a function to setInterval not a string, so you can avoid the implicit use of eval.
setInterval(getAjaxNotice, 300000);
To call getAjaxNotice at the start of the page, put it in a ready block.
$(function(){
getAjaxNotice();
});
A couple of things...
setInterval("getAjaxNotice()", 50000);
Is not 5 minutes.
5 minutes = 300000 milliseconds.
and if you want it to run instantly and THEN do it every 5 minutes you can simply do
$(document).ready(function() {
getAjaxNotice();
function getAjaxNotice() {
$.post("/async/getnotification" ,
{},
function(response)
{
var notice = $(response);
$("#notices").prepend(notice);
});
return false;
}
setInterval( getAjaxNotice(), 300000 );
});
In your situation it sounds like you are dealing with a few problems. So using your current approach, you can initially make your ajax call and follow it up with a set timeout:
getAjaxNotice();
setTimeout( "getAjaxNotice()", 300000);
Secondly, ensuring the user received the message only once can be done easily if you have some type of "message confirmed" event. Assume your user could have browsers open on multiple computers, if you make the user click the message or click an ok button, or perform some action to acknowledge they received the message, you can fire off another ajax call to delete that message from the buffer on your server, yet still display it on all open browsers. The local browser would only display it once because you could prevent displaying it client side if the message is a duplicate (based on what ever criteria makes sense for your application)
However, you should look into long polling and COMET, http://en.wikipedia.org/wiki/Comet_(programming). Comet is a concept around pushing notifications to web browsers based on server side events, as opposed to web browsers constantly asking the server for changes.
Due to limitations in web frameworks and browsers, this was accomplished with a few technologies, but long-polling seems to be the most prevalent. HTML5 and websockets are trying to make some changes that could prevent polling all together, but its not readily available yet.
Long Polling, http://en.wikipedia.org/wiki/Push_technology, and COMET based architecture have been used by companies like meebo and facebook. Don't quote me on this but for some reason I'm inclined to believe facebook uses an Erlang based webserver to serve their chat messages. Erlang and NodeJs are just a couple of solutions you can use to build light weight web servers that work well with tons of long polling requests hitting your servers.
You should definitely go read up on all these things yourself as there is a wealth of information available. I have experimented with create a NodeJs server on Amazon EC2, as I'm traditionally a .NET job and don't feel IIS is the right solution for supporting an the long polling features of a .net application which uses long polling, and I have to say I like NodeJs alot. Plus the javascript language is much more familiar to me than my limited knowledge of Erlang.

Categories