localStorage .parse .stringify - javascript

I need help with pushing 2 data values into localStorage. I know a little about the stringify and parse methods but cant grasp how to implement them.The 2 data values are from "Scores" and "saveName"(a username that is put into an input box).
var Score = (answeredCorrect * 20) + (timeleft);
var saveName = document.querySelector("#saveName");
function Storage() {
localStorage.setItem("User", JSON.stringify(saveName.value));
localStorage.setItem("Scores", JSON.stringify(Score));
var GetStorage = localStorage.getItem("User");
var GetStorage2 = localStorage.getItem("Scores");
return {
first:console.log("GetStorage: "+ GetStorage + GetStorage2),
second:GetStorage,
third:GetStorage2,
};
};
var values = Storage();
var first = values.first;
var second = values.second;
var third = values.third;

As mentioned in the comments you need to parse it once retrieved from storage with JSON.parse, also naming Storage should be avoided.
Since your making a wrapper for localstorage, it could be done like this:
const Store = {
set: (key, value) => localStorage[key] = JSON.stringify(value),
get: key => JSON.parse(localStorage[key])
}
Then you can simply call it like the following, with a set and get methods:
//
Store.set('Score', Score)
Score = Store.get('Score')
//
Store.set('User', saveName.value)
saveName = Store.get('User')
Though you only need to get() on page load as you already have the value in Score/saveName etc.

Related

how to store an array in local storage and then display it in dom

I am trying to save the score of a game in local storage and then access it to display the saved score on my page
I am trying this
const savedScores = [];
function saveRecord() {
localStorage.setItem('scores', JSON.stringify(timeTaken));
savedScores.unshift(JSON.parse(localStorage.getItem('scores')));
}
function veiwRecord() {
setBtnPopup((oldPopup) => !oldPopup);
console.log(savedScores);
return savedScores;
}
and then trying to display it like this
const scoreEl = savedSscores.map((score) => {
return <p> {score} </p>;
});
All localStorage values are in string format, you need to parse the string array into array.
function veiwRecord() {
setBtnPopup((oldPopup) => !oldPopup);
savedScores = JSON.parse(localStorage.getItem("scores"));
console.log(savedScores);
return savedScores;
}
You have to get the Item from localStorage as well in your veiwRecord method.
function set(){
var sendJSON = JSON.stringify(timeTaken);
localStorage.setItem('timeTaken',sendJSON)
}
function get(){
var getJSON = localStorage.getItem('timeTaken');
if (getJSON){
timeTaken = JSON.parse(getJSON)
}
}
You can store arrays and other object types in localStorage using "JSON.stringify", as strings are the only data types that localStorage accepts.
var names = [];
names[0] = prompt("New member name?");
localStorage.setItem("names", JSON.stringify(names));
//...
var storedNames = JSON.parse(localStorage.getItem("names"));
Then you can retrieve stored data with JSON.parse so you can use your array, object etc...

JavaScript - Issues recovering a map in an object after being saved in localStorage

I've been dealing with this for some time. I've a list of sections in which the user checks some checkboxes and that is sent to the server via AJAX. However, since the user can return to previous sections, I'm using some objects of mine to store some things the user has done (if he/she already finished working in that section, which checkboxes checked, etc). I'm doing this to not overload the database and only send new requests to store information if the user effectively changes a previous checkbox, not if he just starts clicking "Save" randomly. I'm using objects to see the sections of the page, and storing the previous state of the checkboxes in a Map. Here's my "supervisor":
function Supervisor(id) {
this.id = id;
this.verif = null;
this.selections = new Map();
var children = $("#ContentPlaceHolder1_checkboxes_div_" + id).children().length;
for (var i = 0; i < children; i++) {
if (i % 2 == 0) {
var checkbox = $("#ContentPlaceHolder1_checkboxes_div_" + id).children()[i];
var idCheck = checkbox.id.split("_")[2];
this.selections.set(idCheck, false);
}
}
console.log("Length " + this.selections.size);
this.change = false;
}
The console.log gives me the expected output, so I assume my Map is created and initialized correctly. Since the session of the user can expire before he finishes his work, or he can close his browser by accident, I'm storing this object using local storage, so I can change the page accordingly to what he has done should anything happen. Here are my functions:
function setObj(id, supervisor) {
localStorage.setItem(id, JSON.stringify(supervisor));
}
function getObj(key) {
var supervisor = JSON.parse(localStorage.getItem(key));
return supervisor;
}
So, I'm trying to add to the record whenever an user clicks in a checkbox. And this is where the problem happens. Here's the function:
function checkboxClicked(idCbx) {
var idSection = $("#ContentPlaceHolder1_hdnActualField").val();
var supervisor = getObj(idSection);
console.log(typeof (supervisor)); //Returns object, everythings fine
console.log(typeof (supervisor.change)); //Returns boolean
supervisor.change = true;
var idCheck = idCbx.split("_")[2]; //I just want a part of the name
console.log(typeof(supervisor.selections)); //Prints object
console.log("Length " + supervisor.selections.size); //Undefined!
supervisor.selections.set(idCheck, true); //Error! Note: The true is just for testing purposes
setObj(idSection, supervisor);
}
What am I doing wrong? Thanks!
Please look at this example, I removed the jquery id discovery for clarity. You'll need to adapt this to meet your needs but it should get you mostly there.
const mapToJSON = (map) => [...map];
const mapFromJSON = (json) => new Map(json);
function Supervisor(id) {
this.id = id;
this.verif = null;
this.selections = new Map();
this.change = false;
this.selections.set('blah', 'hello');
}
Supervisor.from = function (data) {
const id = data.id;
const supervisor = new Supervisor(id);
supervisor.verif = data.verif;
supervisor.selections = new Map(data.selections);
return supervisor;
};
Supervisor.prototype.toJSON = function() {
return {
id: this.id,
verif: this.verif,
selections: mapToJSON(this.selections)
}
}
const expected = new Supervisor(1);
console.log(expected);
const json = JSON.stringify(expected);
const actual = Supervisor.from(JSON.parse(json));
console.log(actual);
If you cant use the spread operation in 'mapToJSON' you could loop and push.
const mapToJSON = (map) => {
const result = [];
for (let entry of map.entries()) {
result.push(entry);
}
return result;
}
Really the only thing id change is have the constructor do less, just accept values, assign with minimal fiddling, and have a factory query the dom and populate the constructor with values. Maybe something like fromDOM() or something. This will make Supervisor more flexible and easier to test.
function Supervisor(options) {
this.id = options.id;
this.verif = null;
this.selections = options.selections || new Map();
this.change = false;
}
Supervisor.fromDOM = function(id) {
const selections = new Map();
const children = $("#ContentPlaceHolder1_checkboxes_div_" + id).children();
for (var i = 0; i < children.length; i++) {
if (i % 2 == 0) {
var checkbox = children[i];
var idCheck = checkbox.id.split("_")[2];
selections.set(idCheck, false);
}
}
return new Supervisor({ id: id, selections: selections });
};
console.log(Supervisor.fromDOM(2));
You can keep going and have another method that tries to parse a Supervisor from localStorageand default to the dom based factory if the localStorage one returns null.

Local storage set Item replaces instead of update

I tried to save my data in local Storage with setItem but when I refresh the chrome tab and add data to my array, the data in localStorage delete the old data and set new data instead of updating that old data.
Here is my code:
let capacity = 200;
let reservedRooms = 0;
let users = [];
let rsBox = document.getElementById('reservebox');
class Reserver {
constructor(name , lastName , nCode , rooms){
this.name = name ;
this.lastName = lastName ;
this.nCode = nCode ;
this.rooms = rooms ;
}
saveUser(){
if(this.rooms > capacity){
console.log('more than capacity');
}else{
users.push({
name : this.name ,
lastName : this.lastName ,
id : this.nCode ,
rooms : this.rooms
});
capacity -= this.rooms ;
reservedRooms += this.rooms ;
}
}
saveData(){
localStorage.setItem('list',JSON.stringify(users));
}
}
rsBox.addEventListener('submit',function(e){
let rsName = document.getElementById('name').value;
let rsLastName = document.getElementById('lastname').value;
let rsNationalCode = Number(document.getElementById('nationalcode').value);
let rooms = Number(document.getElementById('rooms').value);
//Save the user data
let sign = new Reserver(rsName , rsLastName , rsNationalCode , rooms);
sign.saveUser();
sign.saveData();
e.preventDefault();
});
You are pushing an empty users array each time you reload the page, to resolve this you need to populate the users array from the items you have in storage.
e.g.
let users = [];
needs to be something like
let users = JSON.parse(localStorage.getItem('list')) || [];
The key point being that you need to load your existing users to be able to add to them, if you don't then you are essentially creating the users array fresh each time the page loads and you put data into it.
You may want to create something like a "loadData" function that checks if the array is initialized, loads it if it is and creates it if it isn't. You can make this generic so that you can use it to access any key and provide a default value if the key isn't present e.g.
function loadData(key, def) {
var data = localStorage.getItem(key);
return null == data ? def : JSON.parse(data)
}
then
// load "list" - set to an empty array if the key isn't present
let users = loadData('list', []);
Another option would be to change the saveData method so you won't have to load the localStorage when the app is loading:
saveData(){
let newList = JSON.parse(localStorage.getItem('list') || '[]')
if(users.length) newList.push(users[users.length - 1]);
localStorage.setItem('list',JSON.stringify(newList));
newList=null;
}
Note: Be careful with localStorage because it doesn't have the same capacity on all browsers, you can check this post for more information

Update an Object in indexed db by ignoring a value

I have written the below code
updatePublication(projectName, publicationId, publicationObj, callback) {
let self = this;
this.initDatabase(function (db) {
let tx = self.db.transaction(self.PUBLICATIONS, self.READ_WRITE);
let store = tx.objectStore(self.PUBLICATIONS);
let index = store.index(self.PROJECT_NAME);
let request3 = index.openCursor(IDBKeyRange.only(projectName));
console.log("hrere");
request3.onsuccess = function () {
let cursor = request3.result;
if (cursor) {
let updateObject = cursor.value;
if (updateObject.publicationID == publicationId) {
updateObject.publicationObject = publicationObj;
cursor.update(updateObject);
callback(publicationId);
}
cursor.continue();
} else {
callback(publicationId);
}
};
});
}
But this give error:
I checked the cause of error. It is beacuse , publicationObj which is passed has an object named _requestObjectBuilder which is of the type Subscriber.
used somewhere in the code like this:
_requestObjectBuilder = interval(1000).pipe(tap(() => {}));
Is there any way i can modify my updatePublication code to ignore this value?
Does indexed db support a query for ignoring a value and saving the data?
Note: If i set publicationObj._requestObjectBuilder = undefined, the data gets saved to indexedDB. But this breaks the functionality where _requestObjectBuilder is used.
Fixed the issue by cloning the object and setting it to undefined
let clonedObject = Object.assign({}, publicationObject);
clonedObject._requestObjectBuilder = undefined;
Now i am updating the clonedObject

firebase - javascript object returning undefined

I have a firebase set up. here is the structure:
I am having trouble getting the 'newNroomID' value (that is a6QVH, a7LTN etc..).
this value will be use to compare with the other variable value.
I know that in javascript, to access the value of the object it can be done like this:
var card = { king : 'spade', jack: 'diamond', queen: 'heart' }
card.jack = 'diamond'
but it seems different story when it comes with the firebase or surely enough i am missing something. Here is my code.
var pokerRoomsJoin = firebase.database().ref(); // this is how i set it up this block of code is for reading the data only
pokerRoomsJoin.on('value', function(data){
var rID = data.val();
var keys = Object.keys(rID);
var callSet = false;
for (var i = 0 ; i < keys.length; i++) {
var indexOfKeys = keys[i];
var roomMatching = rID[indexOfKeys];
var matchID = roomMatching.newNroomID; // this does not work alwaus give me undefined
console.log('this return :' + matchID + ' WHY!')
console.log(roomMatching)
if(matchID == 'ffe12'){ // 'ffe12' is actually a dynamic value from a paramiter
callSet = true;
}
}
})
and here is the result of the console log:
strangely i am able to access it like this
var matchID = roomMatching.newNroomID // it return a6QVH and a7LTN one at a time inside the loop
only if i set up the ref to :
var pokerRoomsJoin = firebase.database().ref('room-' + roomId);
I've tried searching but seems different from the structure i have . am I having bad data structure? Save me from this misery , thanks in advance!
Let us see the code inside for loop line by line,
1. var indexOfKeys = keys[i];
now indexOfKeys will hold the key room-id
2. var roomMatching = rID[indexOfKeys];
here roomMatching will hold the object
{ 'firebasePushId': { newDealerName: 'b',
...,
}
}
Now
3. var matchID = roomMatching.newNroomID;
This of-course will be undefined because roomMatching has only one
property , firebasePushId.
To access newNroomID , you have to do something like this,
matchID = roomMatching.firebasePushKey.newNroomID .
One way to get firebasePushKeys will be using Object.keys(roomMatching).

Categories

Resources