saving current value of a variable on page reload in JAVASCRIPT - javascript

Is there a way to keep a variable value on page refresh, if I have
var x=0;
but then a users does something that makes that value become
x=4;
and then the page is refreshed, is there a way to keep that value of 4 for the x variable or it will always reset to the original value?
I have written 2 functions to set and get the value like this:
function SetlifeCounter()
{
life = 3;
localStorage.setItem("life", life);
}
function GetlifeCounter()
{
life1 = localStorage.getItem("life");
life1=life1-1;
return life1;
}
And then calling them this way:
var mainLife;
SetlifeCounter();
mainLife=GetlifeCounter();
while(mainLife!=0)
{
window.location.reload();
}
But when I run this the page freezes...
What m I doing wrong??
P.S this is to keep track of the no. of lives in a game every time you die(page reloads) in the game life gets deducted.

Yes, use localStorage.
When using persisted values, you'll need to check to see if a value was already saved (from the user's previous visit) and, if so, use that. If not, you'll need to create a value and set it into storage so that it can be used on a subsequent visit.
This is generally done like this:
var x = null;
// Check to see if there is already a value in localStorage
if(localStorage.getItem("x")){
// Value exists. Get it assign it:
x = localStorage.getItem("x");
} else {
// Value doesn't exist. Set it locally and store it for future visits
x = 3.14;
x = Math.floor(x);
localStorage.setItem("x", x);
}
In your example, you have a variety of issues, but the browser locking up was due to the while loop, which was creating an infinite loop whenever the life count was not zero. You must be VERY careful with while loops and ensure that they will always have a termination condition that will be hit. But, for your purposes, this was unnecessary anyway.
See comments inline below for details on the correct usage of localStorage.
NOTE: This code won't work here in the Stack Overflow code snippet editor due to sandboxing, but you can see this working example here.
// This is where you will store the lives remaining
// You don't need several variables to keep track of this
// (mainLife, life, life1). Just modify this one variable as needed.
var lifeCount = null;
// As soon as the user arrives at the page, get or set the life count
window.addEventListener("DOMContentLoaded", initLifeCount);
// By convention use camelCase for identifier names that aren't constructors
// and put opening curly brace on same line as declaration
function initLifeCount() {
// You need to test to see if an item exists in localStorage before getting it
if(localStorage.getItem("life")){
// And, remember that localStorage values are stored as strings, so you must
// convert them to numbers before doing math with them.
lifeCount = parseInt(localStorage.getItem("life"), 10) - 1;
// Test to see if there are any lives left
if(lifeCount === 0){
// Invoke "Game Over" code
alert("Game Over!");
}
} else {
// User hasn't previously stored a count, so they must be starting a new game
lifeCount = 3;
}
// Any time the count changes, remember to update it in localStorage
updateLifeCount();
// Temporary code for debugging:
console.log("Life count is: " + lifeCount);
}
// Call this function after the life count changes during game play
function updateLifeCount(){
localStorage.setItem("life", lifeCount)
}
If you open your developer tools (F12) and navigate to view the localStorage, you will be able to see the value decrease every time you re-run the Fiddle. You can also see the value in the console.

Many. You can choose between cookies, local storage, web sql, remote backend...
See this question about setting the value inside a cookie:
Set cookie and get cookie with JavaScript
For local storage, use:
localStorage.setItem("x", x);

Related

How to determine if an array of string objects is empty using ngIf?

I have to write a code in which I must transfer some items between two lists and hide an error when the array of object literals to be transferred to isn't empty. I have created two controllers(to manage two separate lists) and one service to deal with common data. A list has been defined inside the service along with some functions to transfer items from one list to another. The array size never seemed to change from 0,which is the logic i am trying to use in ngIf.
My logic was to check if the array is empty, then return a value of true if it was empty and set a variable empty in the controller. Then in ng-if I will check ng-if="b.empty" and thought that that would work but it didnt. The array size would remain 0 all throughout the life cycle of my code. I used ._isEmpty(list),angular([],[]) and the most obvious, array.length but the issue was initially they showed 0, but then the array size never changed. Even after populating the target array, the size seemed to stay 0 with any/all of the above functions/methods.
l1.$inject = ['listService']
function l1(listService){
var buying = this;
buying.items = listService.display();
buying.Add = function ($index){
listService.addItem($index);
}
}; //This is the controller for the source array.
.
.
.
bought.empty = listService.checkIfFull(); //Part of the second controller which assigns empty a boolean value
.
.
.
service.checkIfFull = function (){
if(blist.length == 0){
console.log(_.isEmpty(blist))
console.log(tblist)
return false;
}
else
{
console.log("not going here");
return true;
}
}; //The service checks if the array is empty
<div class="emptyMessage" ng-if="b.empty">Nothing bought</div>
The value of the console.log statements also only seem to be executing in the true portion of the if statement. I found a solution for this, which was to simply check in the html tag itself, if the local list's(that I'm looping through which ng-repeat)length was equal to zero and that worked. But could you please explain why my attempt is wrong? I am a beginner to AngularJs and JS in general so i might have not understood some rules about js and thus written wrong code. Thank you.
Edit: Here's the link to the codepen-> https://codepen.io/meanmanmachineman/pen/RmmdjY
Your problem is caused by the line bought.empty = listService.checkIfFull();. There you are calling to the function listService.checkIfFull() and assigning the returned value to bought.empty. What you should do is to assign the function itself to bought.empty:
bought.empty = listService.checkIfFull;
This way each time bought.empty is evaluated, it returns the current real value.
EDIT:
I'll try to be more explicit about the difference between, bought.empty = listService.checkIfFull() and bought.empty = listService.checkIfFull.
The first way, bought.empty will call to listService.checkIfFull() and store the returned value as a static value and any time the variable is evaluated, the value will be the same.
By using the other method, the value of bought.empty is not a number but the listService.checkIfFull function itself. This way, each time AngularJS evaluates the variable, the function is executed and returns the corresponding value.

How to use localStorage to change value of variable on .js on a HTML file and have the value be retained when on other HTML file?

I have a JavaScript file with some variables on it and multiple HTML files accessing it, but I want it so that when I change a variable in JavaScript, the value is retained in different HTML files and when I reload the page.
say this is my JavaScript file, lets call it variables.js
localStorage.setItem("number", 1);
var number = parseInt(localStorage.number);
console.log(number);
say this is one of my HTML files
<script src="variables.js">
number;
</script>
<script>
/*I've tried all 3 of these separatetly and together, but the value resets back to 10 when accessed on a different HTML file or when I reload the page*/
number = 2;
localStorage.setItem("number", 2);
localStorage.number = 2;
</script>
when I reload the page, the value of the variable resets back to 1 instead of 2
What is the problem here?
The problem is in your first two lines of variables.js:
localStorage.setItem("number", 1);
var number = parseInt(localStorage.number);
Every time variables.js gets loaded (it's called at the top of your HTML file with <script src="variables.js">), the localStorage is set to 1, and considering number is set after that, the local variable number is also set to 1 (which is later outputted to the page).
Instead of setting number to parseInt(localStorage.number), you're looking to retrieve the value from localStorage with localStorage.getItem("number"), and you're looking to do this before modifying it.
To output one value at first, and then a new value the second time the user sees the page, you can check the value is set with if (localStorage.number). If it is set, you set the new value. If it is not set, you set the original value. You'll also want to check this when outputting the value to the page.
This can be seen in the following (sandboxed) StackSnippet:
// Output whatever is in the storage, *if* it is set
if (localStorage.number) {
document.getElementById("output").innerHTML = localStorage.getItem("number");
}
// If the number has already been set to 1, set it to 2
if (localStorage.number) {
localStorage.setItem("number", 2);
}
// Else set it to 1
else {
localStorage.setItem("number", 1);
}
<div id="output">Not set yet!</div>
And in this JSFiddle snippet.
Hope this helps! :)

Numbers not adding to LocalStorage

I want do add numbers to a pre-existing amount in LocalStorage. What I find after is that it is indeed recognised that there is a new amount, but when I refresh the page it doesn't keep to LocalStorage...
//Just making an index
localStorage.setItem("currentUser",10)
//This makes currentUser.whatever into something viable
var currentUser = (JSON.parse(localStorage.getItem('usersArray')))[localStorage.getItem("currentUser")];
//I add the number to the pre-existing amount
currentUser.goldAmount = currentUser.goldAmount + 50;
//For reference 100 is a pre-existing amount for goldAmount, so it should now be 120. It does alert that although when i refresh the page and do it again its not 200, but still 150. It resets back to 100 every restart...
alert(currentUser.goldAmount);
Appreciate the Help :)
Try checking whats inside your JSON and the currentUser object.
Note that if the JSON contains
{"currentUser":{"goldAmount":10}}
Than you will need to read it like
currentUser.currentUser.goldAmount
variable in-json var requested var

How to make javascript write to itself, and then when that code is ran again say it's already been run and add to a counter

I'm somewhat new to javascript, but I had an idea, code where the user inputs code, and the machine remembers and it and assigns it to a random variable name, and spits out the things that happen, and the name of the variable so it can be called again.
Lets say I enter this:
var input1 = prompt("Hi how are you");
if(input1 = "good"){
alert("That's great!");
}else if(input1 = "bad"){
alert("I hope it perks up!");
}else{
alert("Input not recognized");
}
When he/she enters it it then assigns it to a variable first, so any code inside itself can't modify itself before that, so any code that modifies itself doing it won't have to worry, then it runs it. After it runs it displays the variable number so they can call it later.
One thing for the variable I might have to have it check to see if it already exists as a variable name, and if it does it recalculates a variable name.
So basically code that saves it to itself in a variable causing itself to grow.
Self-modifying code is generally not a good idea.
In this case, if all you want to do is remember something in a variable, one option is to use web storage, specifically local storage.
To get the value (with a default if none has ever been stored):
var value = JSON.parse(localStorage.getItem("value") || "0");
To save the value for next time:
localStorage.setItem("value", JSON.stringify(value));
localStorage is the browser-supplied object that manages local storage.
I'm using JSON because web storage only ever stores strings, so my general pattern is to store JSON text. In this specific case, for just a number, it's a bit overkill and you could just use parseInt or the unary + coercion trick:
// Loading
var value = +localStorage.getItem("value") || 0;
// Saving (will implicitly be coerced to a string)
localStorage.setItem("value", value);
I'm also using the curiously-powerful || operator (more about that on my blog)*.
More in the specification and on MDN.
Live Example on jsFiddle (Stack Snippets don't allow using web storage):
HTML:
<input type="button" value="Click Me">
JavaScript:
document.querySelector("input").addEventListener("click", function(e) {
var value = +localStorage.getItem("value") || 0;
++value;
alert("That was click #" + value + " on this browser.");
localStorage.setItem("value", value);
});

Multiple javascript timeouts - problem with live data fetching

I am building a real-time system which (with a use of websockets) updates a table with live data of different frequencies (can be 3 times per second, can be once every 2 seconds - dependant on the type of data).
I am currently struggling to find a way of letting the user know when a particular field has not been updated in the last 5 seconds. That is, if no new data is fetched, I shouldn't keep the old value there, but rather change it to '--' or something similar.
After a long way to the javascript, final function which updates fields looks like that (extremely simplified):
function changeValue(data){
var fieldId= data.fieldId;
var value = Math.round(data.value);
$('span#'+fieldId).text(value);
}
This function gets called each time a field needs to be changed. I've got between 2 and 40 different fields (dependant on the user) that are changed.
What is the best way of setting timers in order to change the values of the fields to '--' every 5 seconds, if no update has been made?
I would be really grateful for some tips,
Thanks,
Karol.
Since you want to indicate timeout on a per-field basis, you have two obvious options:
Have a global interval timer that ticks over fairly frequently and looks through all of your fields for a timeout.
Have independent timers for each field which just deal with that field.
I think on balance I prefer (1) to (2), because we're only dealing with one interval timer then and it makes the housekeeping simpler.
Since IDs in documents must be unique, we can use your field ID values as a key in a hash (an object) to store last updated times. This is kind of a spin on the previous answer but works on a per-field basis. So here's how we'd set those last updated times:
var lastUpdatedTimes = {};
function changeValue(data){
var fieldId= data.fieldId;
var value = Math.round(data.value);
$('span#'+fieldId).text(value);
lastUpdatedTimes[fieldId] = new Date().getTime();
}
Then you set up an interval timer to check each of them.
function checkFieldsForTimeout(){
var now = new Date.getTime();
// For each ID in lastUpdatedTimes, see if 'now minus
// last updated' is > 5000 and is so, set the field
// text to '--' and remove that entry from the last
// updated list with "delete lastUpdatedTimes[itemId]".
}
Should a timed-out field spring back to life, the "--" will be replaced by some real text again.
By deleting the last updated time from "lastUpdatedTimes" whenever we put "--" into a field, we make sure that the interval timer isn't wasting time processing fields that have already been timed out.
This answer was extended to handling multiple fields after the comment by #Andrew (please see also his answer).
Introduce a property updatedTime, which holds the last time the data was updated, in each data. A periodic timer checks updatedTime for all data and updates the text field if appropriate. The check has to be twice as often as the detection period. Your function changeValue() updates updatedTime and the text field.
function checkData() {
var now = new Date.getTime();
for "each data" {
if (now - data.updatedTime >= 5000) {
var fieldId = data.fieldId;
$('span#'+fieldId).text('--');
}
}
}
function changeValue(data) {
var fieldId = data.fieldId;
var value = Math.round(data.value);
$('span#'+fieldId).text(value);
data.updatedTime = new Date.getTime();
}
// Install periodic timer to check last updates:
setInterval(checkData, 5000 / 2); // interval = half the required detection period

Categories

Resources