My variables wont save in the array, they get replaced? help me - javascript

I am trying to save my variables in an array. Theses variables are written in by the user and saved to localStorage when a button is pressed. On my other html page i reach these variables and put them in 3 different arrays(the variables, that go in three arrays). Then the user writes in new text and save to the variables. Now to the problem. The newly created variables don't add to the array, they replace. I'm thinking this is due to to the same variable name however I can't find an solution.
I have tried to change variable names etc for saving the new variable but cant find solution.
//This is html page 2 (gets the items from localhost)
var TankaKostnadVar = localStorage.getItem("StorageKostnadVar");
var TankaLiterVar= localStorage.getItem("StorageLiterVar");
var TankaDatumVar = localStorage.getItem("StorageDatumVar");
var arrayKostnad = [];
var arrayLiter = [];
var arrayDatum = [];
arrayKostnad.push(TankaKostnadVar,);
arrayLiter.push(TankaLiterVar,);
arrayDatum.push(TankaDatumVar,);
document.write(arrayLiter,arrayKostnad,arrayDatum); //Ignore this, just test
//This is the code where the user is writing and it saves to localStorage.
//Html page 1 that saves the variables
var TankaKostnadVar = document.getElementById("tankaKostnad").value;
var TankaLiterVar = document.getElementById("tankaLiter").value;
var TankaDatumVar = document.getElementById("tankaDatum").value;
localStorage.setItem("StorageKostnadVar", TankaKostnadVar);
localStorage.setItem("StorageLiterVar", TankaLiterVar);
localStorage.setItem("StorageDatumVar", TankaDatumVar);
I expect the array to add the variable. So if the user writes an 5 the array should first be [5] then when the user writes an 8 the array should be [5,8]

If you don't want use JSON, you can save string comma separated and, when necessary, transform the items to numbers. To transform in numbers you can use map function or a for. Localstorage only save strings, so if you need to be back to numbers you need to use JSON.parse or use function parseInt, that is global.
//Retrieve saved items from localstorage
var TankaKostnadVar = localStorage.getItem("StorageKostnadVar"); // "1,2"
var TankaLiterVar = localStorage.getItem("StorageLiterVar");
var TankaDatumVar = localStorage.getItem("StorageDatumVar");
TankaKostnadVar += "," + document.getElementById("tankaKostnad").value;
TankaLiterVar += "," + document.getElementById("tankaLiter").value;
TankaDatumVar += "," + document.getElementById("tankaDatum").value;
localStorage.setItem("StorageKostnadVar", TankaKostnadVar);
localStorage.setItem("StorageLiterVar", TankaLiterVar);
localStorage.setItem("StorageDatumVar", TankaDatumVar);
// if you want to transform TankaKostnadVar and others two, just do like this
TankaKostnadVar.split(','); // result: ['1', '2']
// if you want to transform to number
TankaKostnadVar = TankaKostnadVar.split(',').map( function(number) {
return parseInt(number)
} );
The split function of string, breaks a strings in parts separated by one string. In this case, breaks a string separated with comma. So "1,2" turns into ['1', '2'].

If you want to keep adding to the array you'll need to push the entire array you're holding in memory up to localStorage after appending a new element. Alos, localStorage only stores string values so if you want to maintain the Array structure you'll have to use JSON.stringify() before running setItem() and then JSON.parse() next time you access those values with getItem().
//This is the code where the user is writing and it saves to localStorage.
//Html page 1 that saves the variables
var TankaKostnadVar = document.getElementById("tankaKostnad").value;
var TankaLiterVar = document.getElementById("tankaLiter").value;
var TankaDatumVar = document.getElementById("tankaDatum").value;
localStorage.setItem("StorageKostnadVar", JSON.stringify( [TankaKostnadVar] ));
localStorage.setItem("StorageLiterVar", JSON.stringify( [TankaLiterVar] ));
localStorage.setItem("StorageDatumVar", JSON.stringify( [TankaDatumVar] ));
//This is html page 2 (gets the items from localhost)
var TankaKostnadVar = localStorage.getItem("StorageKostnadVar");
var TankaLiterVar = localStorage.getItem("StorageLiterVar");
var TankaDatumVar = localStorage.getItem("StorageDatumVar");
var arrayKostnad = JSON.parse(TankaKostnadVar);
var arrayLiter = JSON.parse(TankaLiterVar);
var arrayDatum = JSON.parse(TankaDatumVar);
// Now you have arrays with data, but I don't know what you want to do with them...
// you could add more values like this (still page 2)...
arrayKostnad.push('new value 1')
arrayLiter.push('new value 2')
arrayDatum.push('new value 3')
localStorage.setItem("StorageKostnadVar", JSON.stringify( arrayKostnad ));
localStorage.setItem("StorageLiterVar", JSON.stringify( arrayLiter ));
localStorage.setItem("StorageDatumVar", JSON.stringify( arrayDatum ));
// now check the values again
var TankaKostnadArr = JSON.parse(localStorage.getItem("StorageKostnadVar"));
var TankaLiterArr = JSON.parse(localStorage.getItem("StorageLiterVar"));
var TankaDatumArr = JSON.parse(localStorage.getItem("StorageDatumVar"));
document.write(TankaKostnadArr, TankaLiterArr, TankaDatumArr)
And this is what I would do to clean things up a little...
// Import these functions and variables to any file that needs to interact with LocalStorage
var storageKeys = ["StorageKostnadVar","StorageLiterVar","StorageDatumVar"];
function addToArray(key, val, arrObj) {
arrObj[key].push(val)
}
function storeAllLocalStorage(arrayObject) {
Object.keys(arrayObject).forEach(key=>{
localStorage.setItem(key, JSON.stringify(arrayObject[key]));
})
}
// Use above functions when needed
var storedArrays = storageKeys.reduce((acc,key)=> {
var val = JSON.parse(localStorage.getItem(key));
if (typeof val === 'array') return {...acc, [key]:val};
return {...acc, [key]:[val]};
},{})
addToArray("StorageKostnadVar", document.getElementById("tankaKostnad").value, storedArrays);
addToArray("StorageLiterVar", document.getElementById("tankaLiter").value, storedArrays);
addToArray("StorageDatumVar", document.getElementById("tankaDatum").value, storedArrays);
storeAllLocalStorage(storedArrays)

You are simply using localStorage.setItem which saves your values with the given key. If the key exists, it will replace the value. Before you do a .setItem, get the value from the local storage first, then parse it to array so that you can finally push the new user inputs to that parsed array. Then you can .setItem to replace the "outdated" value from the localStorage.
UPDATE Example:
Sorry for leaving this hangin without an example. Here it is:
// Get array from local storage
const stringifiedArray = localStorage.getItem('myCollection');
// If there is no 'myCollection' from localStorage, make an empty array
const myCollection = stringifiedArray ? JSON.Parse(stringifiedArray) : [];
myCollection.push('My new item added'); // update array
localStorage.setItem('myCollection', JSON.stringify(myCollection)); // save

Related

How do I calculate the sum of numbers stored in LocalStorage?

I am new to JSON, so bear with me!
I am working on a website that stores values to LocalStorage via inputs. Each form input has the following function (only difference is formInput2, formInput3)
function formInput(e) {
// Save userInput from input
// Get form values
var input = document.querySelector('.input').value;
this.style.visibility = 'hidden';
smtBtn.style.display = 'inline-block'
var userInput = {
answer: input
}
// Test if bookmark is null
if (localStorage.getItem('bookmarks') === null) {
// Init Array
var bookmarks = [];
// Add to array
bookmarks.push(userInput);
// Set to LocalStorage
localStorage.setItem('bookmarks', JSON.stringify(bookmarks));
} else {
// Get Bookmarks from LocalStorage
var bookmarks = JSON.parse(localStorage.getItem('bookmarks'));
// Add bookmark to array
bookmarks.push(userInput);
// Reset back to LocalStorage
localStorage.setItem('bookmarks', JSON.stringify(bookmarks));
}
// Refetch bookmarks
fetchBookmarks();
// Prevent form from submitting
e.preventDefault();
}
I need to add the three numbers that are in local storage, and I am using this function:
function bookmarkMath() {
var bm1 = JSON.parse(localStorage.getItem('bookmarks')),
total = 0,
i;
for (i = 0; i < bm1.length; i++) {
total += bm1[i].answers;
}
console.log(total);
}
}
But alas, my output is NaN. :(
Any help would be very appreciated!!!!!!!
edit: In dev tools, this is what I get back with console.log(LocalStorage) - the numbers I have entered in the form on the site.
Storage {bookmarks: "[{"answer":"2"},{"answer":"4"},{"answer":"5"}]", length: 1}
bookmarks: "[{"answer":"2"},{"answer":"4"},{"answer":"5"}]"
length: 1
__proto__: Storage
Edit 2: I have updated the second ]function to include the JSON.parse. But now I am getting just the numbers 0245 as my result, NOT the sum of 0+2+4+5. Any help?? :p
You are on the right track by doing JSON.parse(). However, the value is in a string. You can see quote at the value it is mean will be threated as a string. You should convert it to number format like following:
total += parseInt(bm1[i].answers);
If you don't want to do parseInt() then your output should be :
{"answer": 2} //this one mean your value is Number
Instead:
{"answer":"2"} //this one mean your value is in String
I think I see it ... this statement looks "wrong, yet something that JavaScript would accept!"
var bm1 = JSON.parse(localStorage.getItem('bookmarks')),
total = 0,
i;
Notice the commas.
Instead, write this as three separate lines:
var var bm1 = JSON.parse(localStorage.getItem('bookmarks'));
var total = 0;
var i;
const bookmarks = JSON.parse(localStorage.getItem('bookmarks')) || []
const totalAnswers = bookmarks.map(o => +o.answer).reduce((a, b) => a + b)

Duplicate an array in an object then update a value based on key - Javascript

I need help doing the following.
I need to duplicate an array, update a value and insert it into a new object.
My Code right now:
// Sample test values {name:'The initial value', altName:'a first Name;a second name'}
var allAltName = test.altName;//Test come from a forEach() Iteration
if (test.altName) {//First I check if ther is my parama altName
var b,
countAllAltName = allAltName.split(';'); //Here I split my parameter string based on ';'
if (countAllAltName.length > 0) {
for (b = 0; b < countAllAltName.length; b = b + 1) {
var originalName = {};//I create a new object
originalName = test;//I load my existing object into a blank object
if (!ret["Index"]) // I check if my final object Key exist
ret["Index"] = {}; // if not create new object
if (!ret["Index"]["Index"]) // check another key
ret["Index"]["Index"] = []; // if not create new
originalName.name = countAllAltName[b];//Update my new object originalName with new value
ret["Index"]["Index"].push(originalName); // push current element in the designated list
ret["Index"]["Index"].sort(function (a, b) {
return a.name.localeCompare(b.name);
});
console.log(ret);
}
}
}
Issue is ret contains the required Object keys,but all value of name in each aray have the same last value of altName
I console.log() at each step what is the value of originalNameit always looks good.
Why the end results failed, and where I'm overwriting my data.
When you write originalName = test, you tell to JS that originalName is an "alias" for test (both share the same reference).
The behaviour is what you change in originaleName, it's impacted in test and vice versa (behaviour true only for Array and Object).
If you want to do a real copy, the simplest way (but with restrictions) is :
originalName = JSON.parse(JSON.stringify(test));
Last things : var originalName = {} is not an Array but an Object. There are some important differences between them

updating javascript object key value

If i try to add more keys with values to a javascript object it alters the value of all keys, not just the one I have added.
var corridorObject = {};
var makeObjects = [];
function someFunction(){
var a = makePoints;
var Corridor = viewer.entities.add({
corridor : {
positions : (a),
width : 10.0,
material : Cesium.Color.GREEN,
}
var idv0 = Corridor.id
corridorObject[idv0] = makeObjects;
console.log(corridorObject);
makeObjects.length=0;
}
The Corridor ID is a guid, the makeObjects an array of objects, when I run this it adds the key perfectly, and the values, but when I run it a second time it adds a new key with the new ID and new values, but it also changes the values for all the other keys to the most recent values.
here is the console, as you can see the first time the array for the ID is 3 long the second time with the same id its 2 long
Object {91ff9967-7019-4e76-846e-c0e125481060: Array[3]}
Object {91ff9967-7019-4e76-846e-c0e125481060: Array[2], 3de2c2b1-5fb6-495c-9034-2b37713e5c30: Array[2]}
Sorry to be more clear, this is from Cesiumjs, its taking points and converting them to a corridor, the corridor id and an array of the points that made it are then added to this object. The array of points is then emptied.
If you are repeating
var corridorObject = {};
var makeObjects = [];
var idv0 = Corridor.id
corridorObject[idv0] = makeObjects;
console.log(corridorObject);
These line of code then It will initialise
var corridorObject = {};
Thats why you will get only one key. Put initialization outside of the iteration

storing forms and their elements values in a variable

I have a single page web app.
For speed, I store each 'page' in the JS.
I have a problem which happens when there is a form on a page. If you fill in the form, and then store it in a js variable, and then retrieve it, the forms values have disappeared?
I use functions like:
var pages_html = {};
var $page = $('#some-page');
store_page($page);
$page.remove();
//some stuff on another page
var $retrieved_page = get_page('some-page');
console.log($retrieved_page.find('#some-input').val())
//consoles log is always blank / ''
function store_page(page){
var page_id = $(page).attr('id');
pages_html[page_id] = $(page);
}
function get_page(page_id){
var page = pages_html[page_id];
return $(page);
}
Everything else seems to work, i can store and retrieve pages as i wish, its just any values of form elements are lost. How can I work around this?
You cannot store it like that. Instead store it as serialized array. which you can then fill it back when needed. serializeArray returns Array of Objects which have name and value
var values = {};
function store_page(page){
var page_id = $(page).attr('id');
pages_html[page_id] = $(page);
values[page_id] = $(page).find("form").serializeArray(); // serialize it
}
function get_page(page_id){
var page = pages_html[page_id];
values[page_id].forEach(function(obj){
page.find('[name=' + obj.name + ']').val(obj.value) // add it again
});
return page; // and then return
}

Get all items in NotesXSPDocument

In my Notes Database, I perform an audit when the document is saved. Pretty easy in LotusScript. I grab the original document (oDoc) from the server, then in the document I modified (mDoc), I do a Forall loop that gets the names of each item; forall item in mDoc.items. Grab the same item from oDoc, execute a function with the new item as an argument that will run down a case statement that will see if its a field we care about. if so, I update a set of list values in the document with "When", "Who", "What field", and the "New Value".
I'm doing this in a server side script. In trying this, I discovered a couple of interesting things;
currentDocument is the NotesXSPDocument that contains everything that was just changed.
currentDocument.getDocument() contains the pre-change values. It also returns a NotesDocument which has the "items" field that I can run through.
Thing is, I need something similar in the NotesXSPDocument. Is there a way in an iterative loop to grab the names and values of all items from there?
Here's the broken code. (Currently it's walking through the NotesDocument items, but those are the old values. I'd rather walk down the XSP document items)
function FInvoice_beginAudit() {
var original_doc:NotesDocument = currentDocument.getDocument();
var oItem:NotesItem;
var oItems:java.util.Vector = original_doc.getItems();
var iterator = oItems.iterator();
while (iterator.hasNext()) {
var oItem:NotesItem = iterator.next();
item = currentDocument.getItemValue(oItem.getName());
if (oItem == undefined) {
var MasterItem = ScreenAudit(doc,item,True)
if (MasterItem) { return true }
} else {
if (item.getValueString() != oItem.getValueString()) {
var MasterItem = ScreenAudit(doc,Item,True);
if (MasterItem) { return true }
}
}
}
}
You can get both versions of a document after submit - the original and the one with changed/new values:
original: var original_doc:NotesDocument = currentDocument.getDocument();
changed: var changed_doc:NotesDocument = currentDocument.getDocument(true);
This way you can compare the items for changes.
But, there is a pitfall: after assigning "changed_doc" to currentDocument.getDocument(true) the "original_doc" has the changed values too because both variables point to the same document. That's why we have to copy all items from currentDocument.getDocument() to a new temporary document first and only after get the changed values with currentDocument.getDocument(true). As an alternative you could read the original document from server like you do in LotusScript.
This is a code for detecting changed items as a starting point:
var original_doc:NotesDocument = database.createDocument();
currentDocument.getDocument().copyAllItems(original_doc, true);
var changed_doc:NotesDocument = currentDocument.getDocument(true);
var oItems:java.util.Vector = original_doc.getItems();
var iterator = oItems.iterator();
while (iterator.hasNext()) {
var oItem:NotesItem = iterator.next();
var itemName = oItem.getName();
var cItem:NotesItem = changed_doc.getFirstItem(itemName);
if (cItem.getText() !== oItem.getText()) {
print("changed: " + itemName);
}
oItem.recycle();
cItem.recycle();
}
original_doc.remove(true);
original_doc.recycle();

Categories