Continuous progression of a variable (chrome extension) - javascript

I want to make a continous counter. I mean, I want to close the page and in the other day open it and continue the counter from where I left.
Like, my counter did count 14235 times in one day. In another day I want it to continue from where I left (14235).
Code I made :
var a = 0; //// a is the "counter"
function count() { ///// function to count
chrome.storage.local.get(['a'], function(value) { return a = value.a;});
a += 1;
chrome.storage.local.set({"a": a}, function(){})
console.log(a)
setTimeout(count, 5000)
}
count()
I get 2 values in console.log, one from 0 and one from 14235, while I want get only one. Help.

Your questions is not getting well seen so I decided help you.
You cannot make a equal the last value, at least I cannot do it.
But you can do a better thing. Call it.
function count() {
if(a === 0){ chrome.storage.local.get(['b'], function(value) { return a = value.b }); } else { chrome.storage.local.set({"b": a}, function(){}) }
/// here, if a = 0 it will get the previous value but if a != 0 it will save the value :D
console.log(a)
setTimeout(count, 100)
a += 1;
}
count()
Hope see you again !

Related

Why won't one part of my javascript function run even though it is syntactically correct?

I'm a programming newbie trying to make a function that asks for a password, but will display an error message if the password attempt is wrong more than five times. I have tried fiddling around with those code a bunch of different ways and it just won't work. I have a variable called count that starts as 0, and each time a wrong password is entered, 1 is supposed to be added to count, and once count is greater than 5, the error message is supposed to be displayed.
document.getElementById("word-checker").onclick = function () {
var count = 0;
var inputValue = document.getElementById("text-input").value;
var secretWord = "password123";
if (count > 5) {
alert("You have had 5 unsuccessful login attempts. You account has been temporarily locked.");
} else if (inputValue == secretWord) {
alert("Your answer is correct!");
document.getElementById("text-input").value = "";
} else if (inputValue!==secretWord) {
count++;
alert("Your answer is incorrect. Please try again.");
document.getElementById("text-input").value = "";
}
}
This is driving me insane. I'm sure it's a simple beginner's mistake though. Any input that would help me understand why this won't work would be met with a lot of gratitude.
You are resetting count to 0 every time the click event is triggered:
document.getElementById("word-checker").onclick = function () {
var count = 0; // <-- button clicked, set the value to zero.
// ...
}
This means that count will never get to 5 (in fact, it never gets to be > 1 either, as when count++ increments the value to 1, it is set back to 0 on the next click). Consequently, the if (count > 5) part of the if statement will never be triggered.
You need to declare count outside of the click event:
var count = 0;
document.getElementById("word-checker").onclick = function () {
// use count here
// ...
}
you are redefining count as 0 every time on the click event. You need to define count as a global outside the function and then ++ on every error.
Also, try to correct your indentation as it helps reading.

JavaScript variable changing between two values on a regular basis [duplicate]

This question already has answers here:
Is there a better way of writing v = (v == 0 ? 1 : 0); [closed]
(31 answers)
Closed 5 years ago.
I want a variable's value regularly changing between 0 and 1. If I have a variable whose value is 0 (counter = 0), how can I increase it by 1 (counter = 1) after a few seconds, then decrease it back to 0 ( counter = 0) after another few seconds? An endless loop basically is what I want.
I'm assuming this will require setTimeout or setInterval, but I've absolutely no idea how I'd go about this. I'm very unfamiliar with the syntax; I'm very much a newbie. Does anyone have any pointers?
Thanks!
You can create an endless, timed loop by having a function that calls itself at the end via setTimeout. See below.
var count = 0;
function flip() {
count = Number(!count);
console.log(count);
setTimeout(flip, 1000);
}
flip();
A more generic approach:
// possible addition: allow user to stop the timer
const rotate = (time, vals) => {
// TODO: handle incorrect vals (non-empty array) or time (positive number)
let idx = 0;
setInterval(() => idx = (idx + 1) % vals.length, time);
return {
get val() {return vals[idx];}
}
}
const toggle = rotate(1000, [0, 1])
toggle.val //=> depends on when you call it, changes every 1000 ms
// but always either 0 or 1.
One advantage of this is that it doesn't keep the value in global scope where someone else can mess with it, but encapsulates it in a closure.
It's more generic because you can easily change the time between updates and you can choose whatever you want for values (for example, rotate(5000, ['foo', 'bar', 'baz').)
var counter = 0;
var changeCounter = function () {
counter = counter === 0 ? 1 : 0;
console.log('counter', counter);
setTimeout(changeCounter, 1000);
}
changeCounter();
This sounds like homework but try this:
var value = 0;
setInterval(
function() {
value = value===0 ? 1 : 0;
console.log('value =', value);
},
1000
);
setInterval will call the function over and over again without needing to call setTimeout over and over again.
setInterval is what you want, as documented in W3C, you should pass a function and a time interval in milliseconds on how often to execute the code.
var counter = 0;
setInterval(function(){
counter = 1 - counter;
//Do what you want with the result...
//alert(counter);
}, 1000);
https://codepen.io/paulodiogo/pen/xPPOKa?editors=1010
Not using global variable...
https://codepen.io/paulodiogo/pen/KyyMXZ

What is the logic behind this double function call with recursion?

Where I currently have the console logs, countdown seems to count down from 10 to 1 (this makes sense) but then after this, way seems to add 15 to the final result of countdown 9 times, but for this to happen, I'd imagine that after each countdown loop, way is called, but that each keeps track of its own value? Any clarification about the Why and When of this logic would be helpful - Thanks!
var countdown = function(value) {
value = value - 1;
if (value == 0) {
return value;
}
console.log("loop 1 " + value);
return way(countdown(value));
};
function way(value) {
value = value + 15;
console.log(value);
return value;
}
countdown(10);
As commented above value is a local variable in either function and thus always bound to the scope of either function. It doesn't actually contribute to confusion aside from expecting too much complexity there. ;)
The behaviour arises from countdown() being called recursively and calling way() has to wait until recursive calls for countdown() are returning. But that's not happening until countdown()'s recursion has stopped at value 0 to be returned eventually. After that countdown() isn't invoked ever again, but since countdown() was invoked recursively and this is bubbling up through all invocations of countdown() there are multiple calls for way() with the result returned from the countdown() called at end which in turn was calling way() with result of countdown() etc. ... ok, got a bit confused here myself.
Since value isn't required to be that complex it might help to eliminate it for reducing code:
function countdown(value) {
if ( value == 1 ) { return 0; } // bail out condition
console.log("loop 1 " + value)
return way( countdown( value - 1 ) );
};
function way( value ) {
console.log(value);
return value + 15;
}
countdown(10);
way() is of no relevance to the recursion and thus might be substituted:
function countdown(value) {
if ( value == 1 ) { return 0; } // bail out condition
console.log("loop 1 " + value)
return countdown( value - 1 ) + 15;
};
countdown(10);
Due to recursion this code is diving into stack 9 frames deep. And then it is bubbling up stack returning the result of every passed frame increased by another 15 prior to bubbling up further on.
So actually, there is only one recursion.
At first, the code starts executing your first call to countdown with argument value=10
Stack: []
Execute countdown(10)
Stack: [countdown(10)]
Then execute way(countdown(9)), and to execute this, JS first evaluates countdown(9)
Stack: [countdown(10), countdown(9), ] and so on, you can imagine, until you reach countdown(0), then start popping out from the stack call.
First stack call resolved, countdown(0) = 0, then call way(0), the console logs 0+15, then countdown(0) eventually returns 15, then pop from stack countdown(1) which is equal to way(countdown(0)), which is way(15), then prints out 30, and so on...
Hope this is clear enough
In order to understand this recursive code, it's easiest to follow the program counter:
function way (value) {
value=value +15
console.log(value)
return value
}
countdown = function(value) {
value = value-1
if (value == 0) {
return value;
}
console.log("loop 1 " + value)
return way(
countdown(value));
};
countdown(10);
Start countdown with 10
value > 0 so run way(countdown(9)) //note: countdown is executed first.
Countdown runs with 9
value > 0 so run way(countdown(8)) //note: countdown is executed first.
...
...
...
value == 0, return 0 (in countdown): execute way
way returns 0 + 15
way returns 15 + 15
way .... etc.
As fora clarification why this logic would be helpful; I think there is a lesson to be learned here.
Basically there are 2 relevant function-call positions when applying recursion:
positioned before recursive call
positioned after recursive call
I will leave it as an exercise of why this has any relevance.

Problems using setInterval and clearInterval more than once

I'm getting confused with what's happening here. The quiz works fine the first time. After the first play, though, I get all sorts of problems. I want to click the same button,"#start2", to start and also restart the quiz, ie clear the timer, put all variables back to 0 etc, and display the first question. As if the page had been refreshed, basically.
Instead, I'm getting faster ticking, the timer is incrementing on correct guess and so on. Horrible.
I've used modulo to measure how many times the "#start2" div is clicked. On first click, start timer. On second click - I want to reset the timer. Third click - start timer, and so on.
Any help is massively appreciated.
var n = 0;
var x = 0;
var p = 0;
var incTime;
function a(n) {
var x,y,z;
x = Math.floor((Math.random() * 3))
if(x == 0){y = 1; z = 2}else if(x == 1){y = 0; z = 2}else{y = 0; z = 1}
$("#question_holder2").text(questions[n].q);
$(".answer_holder2").eq(x).text(questions[n].a).data('answer', 'a');
$(".answer_holder2").eq(y).text(questions[n].b).data('answer', 'b');
$(".answer_holder2").eq(z).text(questions[n].c).data('answer', 'c');
}
$(document).ready(function() {
//timing element
function startTimer(x){
$("#start2").text(x);
}
$("#start2").click(function(){
var setTimer;
p++;
//if it's been clicked before
if(p%2 === 0){
clearInterval(setTimer);
$("#start2").text("Start");
n = 0;
x = 0;
a(n);
alert("okay");
}else if(p%2 !== 0){
//never been clicked before
a(n);
setTimer = setInterval(function(){startTimer(x=x+1)}, 1000);
$('.answer_holder2').click(function() {
//correct answer given
if ($(this).data('answer') === 'a') {
n++;
if (n < questions.length) {
a(n);
} else {
alert("End of quiz!");
clearInterval(setTimer);
$("#start2").text("You took " + x + " seconds, you answered " + n + " questions correctly, with - incorrect answers given.");
x = 0;
n = 0;
a(n);
}
}else{
//incorrect answer given
$(this).fadeTo(1000,0.4);
var timeString = $("#start2").text();
var incTime = (timeString * 1) + 5;
$("#start2").text(incTime);
startTimer(incTime);
x = incTime;
};
});
};
});
});
You have this:
$("#start2").click(function(){
var setTimer;
p++;
//if it's been clicked before
if(p%2 === 0){
clearInterval(setTimer);
//....
In this case, when you set to the clearInterval line, setTimer will always be 0, and not the id of a running timer. So this is not actually stopping any timer. If you don't stop the timer it will continue to run. So the function here:
setTimer = setInterval(function(){startTimer(x=x+1)}, 1000);
Will continue to run. So the next time you create a timer, you now have two timers updating x and it'll look like it's running faster.
Try this:
$(document).ready(function() {
var setTimer;
$("#start2").click(function(){
// the rest of your click handler code...
});
//timing element
function startTimer(x){
$("#start2").text(x);
}
}
Your setTimer variable needs to exist in a scope outside of your click handler. As you had it you were declaring a new variable every time so when you try and clear the timer, you are not actually clearing the timer.
Also: freakish's point about how you are reattaching the click handler is also a problem. You need to fix that too.
The answer is that bad things happen because of this:
$("#start2").click(function(){
// some code...
$('.answer_holder2').click(function() {
// some code...
});
});
When you click on #start2 new handler is attached to .answer_holder2. So after for example 3 clicks, .answer_holder2 has 3 handlers attached to it and when you click on it all 3 fire.
You're code is a bit complicated and I'm not going to give you a solution how to fix that. But I can give you a hint. Put inner .click outside of outer .click. You will have to change some code probably, but that has to be done.
EDIT What you could try ( as a fast fix, but not necessarly good ) is adding this:
$('.answer_holder2').off( "click" ).click(function() {
Additonally have a look at Matt's answer.

Javascript prev/next buttons populated from database

I'm trying to use javascript for next and previous buttons that cycle through a list of professors in a database. The code I have works except for one bizarre glitch: when there are over 9 professors (for this example there will be 11 professors), clicking the "previou"s button on Prof2 displays Prof1, Prof10, & Prof11 simultaneously.
Similarly, clicking "next" on the last prof, like Prof11 in this example, displays Prof1, Prof10, & Prof11 simultaneously. Can you spot the error? Is there a simpler way to create these buttons? Thank you in advance.
$.vars = {
counter : 2,
limit : $getUnitFacultyPages.TotalItems,
};
function nextItem() {
$('li','#profs')
.fadeOut('slow')
.filter( function() { return this.id.match('profs' + $.vars.counter); })
.fadeIn('slow');
$.vars.counter == $.vars.limit? $.vars.counter = 1 : $.vars.counter++;
}
function prevItem() {
$.vars.counter -= 2;
if($.vars.counter == 1){
$.vars.counter = $.vars.limit;
} else if ($.vars.counter < 0){
$.vars.counter = $.vars.limit -1;
}
nextItem();
}
$("#profs-next").click(function () {
nextItem();
});
$("#profs-prev").click(function () {
prevItem();
});
One thing that stands out is use of match that would "match" the regular expression and would cause the behavior that you describe. This should be changed the equality.
return this.id.match('profs' + $.vars.counter);
should be
return this.id == 'profs' + $.vars.counter;
There could be other things as well.
Not sure whether or not this will solve your problem, but there are a couple things that look a little suspect to me at a glance:
Why do you decrement by 2?
You're checking if $.vars.counter == 1 or $.vars.counter < 0. What happens if $.vars.counter == 0?
Edit:
Also, your prev/next logic is a little strange (imo). Ignoring your display logic, I might change it to:
$.vars = {
idx: 0,
limit: 5,
};
function nextItem()
{
$.vars.idx = $.vars.idx >= $.vars.limit ? 0 : ++$.vars.idx;
}
function prevItem()
{
$.vars.idx = $.vars.idx <= 0 ? $.vars.limit : --$.vars.idx;
}

Categories