Expiring a javascript variable? - javascript

I saved some data returned from ajax in javascript variable. I would like to invalidate this variable after some time period, say one hour.
I can potentially write some setTimeout functions to handle this, but I just feel this is not optimal.
Another way is to save in cookie and set expiration, but the overhead may be unnecessary.
Is there other way that can handle this situation more elegantly?

Assuming the actual variable actually exists that long (the page stays open), just do what every cache does: save a timestamp and check for it.
var cache = { timestamp : null, data : null };
function setData(data) {
cache.data = data;
cache.timestamp = new Date;
}
function getData(maxAge) {
if (/* compare cache.timestamp to now - maxAge */) {
return null;
}
return cache.data;
}

Keep a variable that indicates when the value expires.
var foo = "bar";
var foo_expires_on = new Date(new Date().getTime() + 60 * 60 * 5); // +5 hours
deceze's answer is a more formal (monad) implementation.

Related

Replace builtin Date without being able to recover original constructor

I want to replace Date inside a JavaScript VM (V8 but this is not specific to V8), and make it impossible to access the original Date constructor. This is meant to be one part of a defence against timing attacks like Spectre with multi-tenant JavaScript running in the same process (but different JavaScript VM.) The idea is to deny access to high resolution timers. Cloudflare does this in their Workers, for the same reason. Time is advanced only when IO happens, not during computation. I know there are other ways to construct a timer, but I'm just focused on Date for this question.
I think this can be done in pure JavaScript, and this is my attempt. Is there a way to get the original Date constructor back after running this? Is there a way this differs functionally from the builtin Date - something that could break backwards compatibility?
// Current UNIX timestamp in milliseconds, but that we set manually on each call to runTasks.
// not advancing time during computation is one of our defenses against Spectre attacks.
let NOW = Date.now();
export function setDate(unixTimestampMillis) {
NOW = unixTimestampMillis;
}
Date = function (BuiltinDate) {
function Date(...args) {
if (new.target === undefined) {
// This is the deprecated naked Date() call which returns a string
return (new BuiltinDate(NOW)).toString();
}
// Otherwise it was the constructor called with new
if (args.length === 0) {
// Return the "current" time.
return new BuiltinDate(NOW);
}
// Build a Date with the specified datetime
return new BuiltinDate(...args);
}
// Make a copy of the BuiltinDate "class" and replace the constructor,
// It needs to be impossible for the user to grab an reference to BuiltinDate.
Date.prototype = BuiltinDate.prototype;
BuiltinDate.prototype.constructor = Date;
// Add the static methods now(), UTC(), and parse() - all of which return a numeric timestamp
function now() {
return NOW;
}
Date.now = now;
Date.parse = BuiltinDate.parse; // returns a number
Date.UTC = BuiltinDate.UTC; // returns a number
return Date;
}(Date);

Why Use Function Parameters Vs. Global Variables?

Yes, I know that this is probably a very stupid question, but this has been bugging me for a while.
Ok, so I have been learning JavaScript for a while now and have understood everything perfectly. . .except for function "parameters" (I believe they are called).
I was taught that they work like so:
function test(number) {
document.write(number);
};
test(1);
test(12);
This makes perfect sense to me. However, recently, I've come across some that were a little different.
var counterDays = document.getElementById('days');
var counterHours = document.getElementById('hours');
var counterMinutes = document.getElementById('minutes');
var counterSeconds = document.getElementById('seconds');
var date = new Date('December 28, 2016 00:00:00');
function updateTimer(date) {
var time = date - new Date();
return {
'days': Math.floor(time / (1000 * 60 * 60 * 24)),
'hours': Math.floor((time/(1000 * 60 * 60)) % 24),
'minutes': Math.floor((time / 1000 / 60) % 60),
'seconds': Math.floor((time / 1000) % 60),
'total': time
};
};
function startTimer(counterDays, counterHours, counterMinutes, counterSeconds, date) {
var timerInterval = setInterval(function() {
var timer = updateTimer(date);
//Changes the text of the 'counter'
counterDays.innerHTML = timer.days;
counterHours.innerHTML = timer.hours;
counterMinutes.innerHTML = timer.minutes;
counterSeconds.innerHTML = timer.seconds;
window.onload = function() {
startTimer(counterDays, counterHours, counterMinutes, counterSeconds, date);
};
<span id="days"> </span>
<span id="hours"> </span>
<span id="minutes"> </span>
<span id="seconds"> </span>
What I seriously do not understand is why the updateTimer always needs date within the parentheses, when the variable date is an already existing variable within the global scope. Same with startTimer. I don't understand why I need to pass that in. Why not just access the variable within the function, as they do have a global scope, and be done with it. Instead I need to pass in the variable as a parameter, for the function to work.
I've tried and tried, but the only way to make the function work is by passing in the variables. Why is that???
As I am still learning, I've searched the internet for more information on functions and their parameters, but all show me something similar to my first example. I know this is all probably just going over my head, but for the life of me, I just do not understand.
Note: I am still learning, so sorry if this whole question is plain stupid.
Also, the the code for the JS that I am having a problem with won't actually run. This is due to me not wanting to put in all of my code, but rather just the code I am having trouble with.
Instead I need to pass in the variable as a parameter, for the
function to work.
You dont need to define your functions with parameters. You can invoke them leveraging higher scope variables
https://developer.mozilla.org/en-US/docs/Glossary/Scope
This:
var x = 'baz';
function foo(x) {
return x;
}
foo(x);
will do the same thing as:
var x = 'baz';
function foo() {
return x;
}
foo();
Writing functions that take parameters as input helps keep your code modular and side effect free among many other benefits...
1.) The second example will always throw an error if x is not accessible at a higher scope
2.) If another function mutated the value of x it would affect the output of the second example and would lead to unexpected and potentially hard to debug behavior in your application. Whereas I can always be sure of the output of the first example
3.) It is much easier to read through and maintain code that is written in the style of the first example
As I see see your code
var timer = updateTimer(date);
Kindly remove date parameter here as well as in the called function. Now the date variable will work as in global scope.
So it will be
function updateTimer()
{
//date variable will be present here as global variable
}
var timer = updateTimer();

How to periodically update a variable using meteor

I have a session variable that I want to update with a fixed periodicity. Say, I want this variable to be increased by 1 every 60 seconds.
It seems to me that the best place for doing this is inside the helpers section of the relevant template. I first tried to do this using setInterval as described here, but that didn't work (the function just didn't seem to repeat).
I then tried what I thought would be a straightforward solution, but this also doesn't work. See below. The helper variable 'currentPosition' is supposed to return the current minute of the day (plus an offset). However, it only does this when the template is first called and when the session variable 'offset' is changed in a function that's defined in the 'events' section, which responds to a click on a particular div (a 'next' button).
currentPosition: function () {
var d = new Date();
var h = d.getHours();
var m = d.getMinutes();
var w = h * 60 + m;
Session.set("position", w + Session.get("offset"));
return Session.get("position");
},
I would think that the above helper would actively update the value for 'currentPosition' every minute. Yet it does not.
So, my question is, how can I have a session variable change every, say, 60 seconds, increasing it by, say, 1, while the new value of the session variable is reflected within the app, when the variable is adjusted.
(If there's a straightforward and completely different solution which works in meteor, I'm not aware of it, so do point it out to me if I'm missing something obvious.)
Although you are using a reactive variable, it only gets set once - when the helper is first called. Therefore it doesn't run again. You need a function outside of the helper to set variable for you. Remember one important rule - helpers should never have side effects.
Here's a complete working example of how to create a timer:
html
<body>
{{> timer}}
</body>
<template name="timer">
<p>Total Seconds: {{seconds}}</p>
</template>
js
Template.timer.helpers({
seconds: function() {
return Template.instance().seconds.get();
}
});
Template.timer.created = function() {
var self = this;
this.seconds = new ReactiveVar(0);
this.handle = Meteor.setInterval((function() {
self.seconds.set(self.seconds.get() + 1);
}), 1000);
};
Template.timer.destroyed = function() {
Meteor.clearInterval(this.handle);
};

Javascript variable that always returns value of function

I'm pretty sure I know the answer to this (and that it is no), but is it possible to create a variable that always returns the value of a function without "calling" the variable?
I'm sick of an inactivity warning on a website I use. I look at it a few times a day, but I keep it open in case there's an update I need to look at. It automatically signs me out after 15 minutes using some javascript--the token isn't invalidated by a cookie expiring, nor is my session removed server-side--and the variable it checks is called last_user_action.
I'd like to make last_user_action always point to new Date().getTime();.
last_user_action = function() { new Date().getTime(); }
would work if I could easily change all the references to last_user_action to instead belast_user_action(), but I can't.
last_user_action = (function() { return new Date().getTime(); })();
only sets the value once.
So like I said, I doubt there's a way to do this, but if it is possible, how would I do it?
EDIT
It occurs to me now, it'd be easier to just run
window.setInterval(function() { last_user_action = new Date().getTime(); }, 1000 * 60 * 10);
in Chrome's javascript console.
Well, if you are sure it works that way, you could use setInterval every minute to set the value:
setInterval(function(){
last_user_action = new Date().getTime();
},60000)
Not that directly, but it would be trivial to just update the variable periodically.
function updateLastUserAction() {
last_user_action = new Date().getTime(); // or Date.now();
setTimeout(updateLastUserAction, 10000); // run again in 10 seconds
}
updateLastUserAction();
You can change the update period to suit you - since the update function is extremely lightweight, you can run it pretty often and it won't matter.
Assuming last_user_action is a global variable, that means it's actually a property of window and you can define a getter for that property.
Object.defineProperty(window, 'last_user_action', {
get: function() {
return new Date().getTime();
}
});
last_user_action; // 1412882205169
last_user_action; // 1412882206490
This would normally be a bad idea, but given you are hacking here, it doesn't seem so bad.
AFAIK you can't do that with a variable.
But you can do it with a property, using a getter:
var obj = {};
Object.defineProperty(obj, 'last_user_action', {
get: function() { return new Date().getTime(); }
});
obj.last_user_action; // Current date time

Checking how much time passed from creating objectid in mongodb

I'm building an app that allows the user to reset his password.
The process is really simple .The user enters his email address and I sending him a link with the number of the new objectid that was created.
For exemple -> /reset-password?x=55555444475d41a000001.
After clicking the link he reaches other page and then I want to check if 24 hours have passed from the time he got the link?and yes i know there is function called "getTimestamp" but how to use it..?
get: function (request, response) {
???????
},
You can set a "creation_date" property in your object when you create it, like this:
obj = {
id: "xxxxxx...",
creation_date: new Date()
...
}
Then you store the object somewhere in your server, and then when the user opens the link with the id of the object you will do something like this to check if the object has been created more than 24hours ago:
var now = new Date();
if (now - obj.creation_date > 86400000) {
// more than 24h (86400000ms = 24h)
// do something
}
Actually reading the JavaScript API docs for ObjectId might help.
Checking wether 24 hours have passed since the creation of the object should be as easy as
var now = new Date();
/* Subtract the milliseconds a day lasts from the current time.
* If the timestamp of the ID converted to msecs after epoch is smaller
* the ObjectId was created before that.
*/
if ( myId.getTimestamp() < ( now.getTime() - 86400000 ) {
console.log("24 h have passed since creation");
}
else {
console.log("24 h haven't passed since creation");
var passed = new Date( now - myId.getTimestamp() );
console.log(passed.getUTCHours()+":"+passed.getUTCMinutes()+" have passed.");
}
Note: I downvoted your question as it would have been easily solvable by googling "MongoDB ObjectId getTimestamp JavaScript api", you didn't show any sign of working on the problem yourself and didn't bother to ask a specific question. May I politely suggest reading ESR's How To Ask Questions The Smart Way, especially the chapter about StackOverflow?

Categories

Resources