Building an Array in LocalStorage - javascript

I am trying to build an array in localstorage based on a product view history on an ecommerce site. Every time a user views a product page I want to add the ID of this page into the array in local storage.
var itemArray = [];
var myItem = $("li#ref").data("ref");
itemArray.push(myItem);
var LS = {
set: function (key, val) {
return localStorage.setItem(key, JSON.stringify(val));
},
get: function (key) {
return JSON.parse(localStorage.getItem(key));
}
};
LS.set("Viewed", itemArray);
The problem I have is it never builds an array the latest product I look at just overides the one before so I only ever get one entry.
Do you know if this is possible to achieve?
thanks in advance
Richard

You need to append new value to existing array stored in local storage, not new empty array:
var LS = {
set: function (key, val) {
return localStorage.setItem(key, JSON.stringify(val));
},
get: function (key) {
return JSON.parse(localStorage.getItem(key));
}
};
var itemArray = LS.get('Viewed') || [];
var myItem = $("li#ref").data("ref");
if (itemArray.indexOf(myItem) !== -1) {
itemArray.push(myItem);
}
LS.set("Viewed", itemArray);
You should probably also check if the value is already in array to avoid duplicates.

Related

Removing local storage item with vanilla javascript

I'm working on a simple to-do list with vanilla js. I've managed to add the input to local storage, but have not been able to add the style changes(check strike through) to local storage, nor can I figure out how to remove one item at a time from storage. I have been able to clear all, just unable to remove each item separately. Below is my code, any advice is greatly appreciated.
//local storage setup
let saved = window.localStorage.getItem(input.value);
if (saved) {
list.innerHTML = saved;
}
//handle input submit
function handleSubmitForm(e) {
e.preventDefault();
let input = document.querySelector('input');
if (input.value != '') {
addTodo(input.value);
}
input.value = '';
window.localStorage.setItem(input.value, list.innerHTML);
}
//check off todo
function checkTodo(e) {
let item = e.target.parentNode;
if (item.style.textDecoration == 'line-through') {
item.style.textDecoration = 'none';
} else {
item.style.textDecoration = 'line-through';
}
window.localStorage.setItem(item);
}
//delete todo
function deleteTodo(e) {
let item = e.target.parentNode;
item.addEventListener('transitionend', function () {
item.remove();
});
item.classList.add('todo-list-item-fall');
window.localStorage.removeItem(item);
}
JavaScript Storage is a key-value pair. Just use a string-based key so you can remove, edit or read it easily.
// Set todo item
localStorage.setItem("todo1", "Stand-up meeting 9.15am");
// Read todo item
localStorage.getItem("todo1");
// Delete todo item
localStorage.removeItem("todo1");
It's better if you can save it as a JSON string because you can mark it as completed without delete, so you can find completed tasks too.
// Saving todo item as a JSON string
localStorage.setItem("todo1", JSON.stringify({ text: "Stand-up meeting 9.15am", completed: false }));
// Read it
const todo = JSON.parse(localStorage.getItem("todo1"));
// You can read the text
console.log(todo.text);
// Also you can mark it as completed and save it back
todo.completed = true;
localStorage.setItem("todo1", JSON.stringify(todo));
Storing object in localStorage is a tricky job.
Everything you store in the local or session storage is of type string
you can create an object like
item = {
value : ANY_VALUE
}
and save it in your localStorage using JSON.stringify
localStorage.setItem(`item`,JSON.stringify(item))
now when you want to update the item just update the object and again set using the ablove syntax
To access the saved item from the local storage use JSON.parse
yourItemObject = JSON.parse(localStorage.getItem())```
You can access values now using yourItemObject .value
It appears you're passing the whole HTML element (it passed as an object) inside the removeItem function. you need to pass the key instead.
try localStorage.removeItem(item.innerText);
If you are working with lists in localStorage. I would use something like this basic example:
function addTodo(key, item){
var list = getTodo(key);
list.push(item);
localStorage.setItem(key, JSON.stringify(list) );
}
function getTodo(key){
try{
var rawList = localStorage.getItem(key);
return JSON.parse(rawList) || [];
}
catch(e){
return [];
}
}
function removeTodo(key, id){
var list = getTodo(key);
var newlist = list.filter( function(item){
return item.id != id;
});
localStorage.setItem(key, JSON.stringify(newlist) )
}
function emptyTodo(key){
localStorage.removeItem(key);
}
addTodo('list', {
id: 1,
text: 'do shopping'
});
addTodo('list', {
id: 2,
text: 'study'
});
console.log( getTodo('list') );
removeTodo('list', 1);
console.log( getTodo('list') )
emptyTodo('list');

How to append a string to session storage keys?

I want to append the string to keys in session storage i tried below code but it is not working
var setSession = window.sessionStorage.setItem.bind(window.sessionStorage);
window.onload = function()
{
window.sessionStorage.setItem = function(key, value) {
var newKey = "1234"+"::"+key;
alert("inside account new key "+newKey);
return setSession(newKey, value);
}
}
Any suggestions more appreciated...
Not sure what you're after by using localStorage and sessionStorage but here's how to add a prefix to the key and don't do it again if the prefix already exists. Additionally it removes the original keys:
Object.keys(localStorage).forEach(function(key) {
if(/^1234::/.test(key)) return; // Don't repeat if "1234::" exists already
localStorage[`1234::${key}`] = localStorage[key];
delete localStorage[key];
});
if the prefix 1234 is a variable than you could do it like:
let ID_key = '1234';
Object.keys(localStorage).forEach(function(key) {
if(new RegExp(`^${ID_key}::`).test(key)) return; // Don't repeat if 1234 exists already
localStorage[`${ID_key}::${key}`] = localStorage[key];
delete localStorage[key];
});
If I've understood correctly, you want to change the key of an item in session storage?
You could try using the code below.
function changeKey(oldKey, newKey) {
var item = sessionStorage.getItem(oldKey)
sessionStorage.setItem(newKey, item)
sessionStorage.removeItem(oldKey)
}
If you wanted to append a string, you could use this instead:
function appendToKey(oldKey) {
var item = sessionStorage.getItem(oldKey)
oldKey = '1234' + '::' + oldKey
sessionStorage.setItem(newKey, item)
sessionStorage.removeItem(oldKey)
}

save table rows count in local storage

Hello I am currently using a script that takes your table data and saves it in local storage where I call it in another js file.
I have a script that succesfully can save the table data exactly how I would like, But I have been struggling on how to implement a count for how many table rows there are in the table before the data is saved in local storage.
Here is what I have tried:
$(function() {
loadAllTasks();
$("#addTask").click(function() {
let cells = Array.prototype.map.call($("#items-table")[0].rows, row => {
return Array.prototype.map.call(row.cells, cell => cell.innerHTML);
});
var task = {
cells: cells
};
task.Name = $("#taskName").val();
var itemCount = $("#items-table tr").length - 1;
var count = {
itemCount: itemCount
};
saveTaskInStorage(task);
saveCountInStorage(count);
});
function saveTaskInStorage(task) {
var savedTasks = JSON.parse(localStorage.getItem('tasks'));
if (!savedTasks || typeof(savedTasks) !== "object")
savedTasks = {};
savedTasks[task.Name] = task;
localStorage.setItem('tasks', JSON.stringify(savedTasks));
alert("Task has been Added");
}
function saveCountInStorage(count) {
var savedCount = localStorage.getItem('counts')
savedCount = {};
savedCount[task.Name] = count;
localStorage.setItem('counts', savedCount);
}
function loadCountFromStorage1(taskName) {
var savedCount = localStorage.getItem('counts');
return savedCount[taskName];
}
function loadAllTasks() {
var savedTasks = JSON.parse(localStorage.getItem('tasks'));
if (!savedTasks || typeof(savedTasks) !== "object")
return;
for (var taskName in savedTasks) {
$("#loadTask").append('<option>' + taskName + '</option>')
}
}
});
function loadTaskFromStorage1(taskName) {
var savedTasks = JSON.parse(localStorage.getItem('tasks'));
return savedTasks[taskName];
}
then in the other js file I call these functions:
function loadAllTasks() {
// Get all saved tasks from storage and parse json string to javascript object
var savedTasks = JSON.parse(localStorage.getItem('tasks'));
// To be sure that object exists on localStorage
if (!savedTasks || typeof (savedTasks) !== "object")
return;
// Get all property name of savedTasks object (here it means task names)
for (var taskName in savedTasks){
$("#select-task").append('<option>' + taskName + '</option>')
}
}
function loadTaskFromStorage(taskName) {
var savedTasks = JSON.parse(localStorage.getItem('tasks'));
// Return the task by its name (property name on savedTasks object)
return savedTasks[taskName];
}
function loadCountFromStorage(taskName) {
var savedCount = localStorage.getItem('counts');
return savedCount[taskName];
}
loadAllTasks();
var task = loadTaskFromStorage($("#select-task").val());
then I just do:
alert(task.cells);
this works perfectly, it alerts all the custom saved data in the table that I saved.
I then have tried a bunch of different options for this:
alert(task.itemCount);
and a bunch of variations of that.
I want to be able to do:
alert(task.count);
this then will alert me the number of rows in the table of the saved task I currently have selected in my select html.
I also tried getting rid of the saveCount functions and just modifing this:
var task = {
cells: cells,
count: count
};
but unfortunately this also does not work.
I would really appreciate it if anyone could help me on how I would save the table row count in local storage and be able to call it on each different saved task in the select on my html/ js file.
each saved task will have a different count so I want to do task.count
Thanks for the Help <3!
You should really look into using a front end framework like React or Angular. You are looping through dom elements and saving its inner html as values in your task when what you really need is something data driven. However, I think this might solve your issue.
In your click handler for #addTask you have
let cells = Array.prototype.map.call($("#items-table")[0].rows, row => {
return Array.prototype.map.call(row.cells, cell => cell.innerHTML);
});
var task = {
cells: cells
};
Try adding in a counter here
let count = 0;
let cells = Array.prototype.map.call($("#items-table")[0].rows, row => {
count += 1;
return Array.prototype.map.call(row.cells, cell => cell.innerHTML);
});
var task = {
cells: cells
count: count
};
Hopefully that works for you

Trying simplify checking if object key is true and pushing it to another object

I'm building a form to interact with a remote API by building a GET request query string based on what checkboxes the user selects.
My initial thought was to do a laundry list of if/else checks to see if the model object key is true or not and then make a clean array out of just the object key names. However, would there be a more automated way to do it?
I was thinking something along the lines of an angular.foreach, but I can't figure out how to get the object key names to come out as a value.
For example:
function submit() {
var pushData = [];
angular.foreach(vm.export, function(item, index){
if (item == true) {
pushData[item];
}
})
}
Here is the object it's pulling from:
vm.export = {
'servers': true,
'apps': false,
'users': true,
'userID': 1234
}
How can I push the key names with TRUE values to the pushData array?
The foreach has an item (the object/primitive in the array) and a key.
so your pushData is getting a key called "true"(the value of item) instead of the name(the key).
var pushData = [];
angular.foreach(vm.export, function(item, key){
if (item === true) {
pushData[key];
}
});
Why not just use a for in loop?
Working Example
function submit(){
var pushData = [];
for (var prop in data) {
if (data[prop] === true) {
pushData.push(prop);
}
}
return pushData;
}

Storing Json in localStorage

I would like to store search results as cache in localStorage.
I would like to store all the cache as one localStorage value:
localStorage.getItem('search-cache')
Inside it I would like to have JSON object which I can add properties and retreive them.
Unfortunately it doesn't work and the localStorage is not updated with the json results (its value keep being '{}').
I am not a javascript proffesional so please guide me how to do it well.
Here is the current code to cache results:
var query = $(this).val();
var cache = JSON.parse(localStorage.getItem('search-cache'));
if (cache == null) {
cache = '[{}]';
}
if (cache[query] == null) {
$.getJSON('/api/guides/search?query=' + query, function (data) {
$.each(data, function (index, guide) {
$('#results').append('<li class="result-item">' + guide.Name + '</li>');
});
cache[query] = data;
localStorage.setItem('search-cache', JSON.stringify(cache));
});
}
else {
$.each(JSON.parse(localStorage.getItem('search-cache')[query]), function (index, guide) {
$('#results').append('<li class="result-item">' + guide.Name + '</li>');
});
}
You've got some holes in your logic.
var cache = JSON.parse(localStorage.getItem("..."));
if (cache == null) { cache = "[{}]"; }
Well, if the item DID exist, you've set cache to be equal to that object.
Otherwise, you've set cache to be equal to the string "[{}]".
Instead of thinking about how you're going to build your localstorage, think about how you're going to build your result list.
var cache_json = localStorage.getItem("search-cache"),
search_cache = JSON.parse(cache_json) || {};
var query = $("...").value(); // or whatever
search_cache[query] = search_cache[query] || { results : [] };
var list = $(......)
list.each(function () {
search_cache[query].results.push( /* whatever you want in your array */ );
});
cache_json = JSON.stringify(search_cache);
localStorage.setItem("search-cache", query_json);
Because, in case of your item search-cache is not defined, the initialization of your cache variable is not right.
You should initialize your array like this :
if (cache == null) {
cache = [];
cache[query] = null;
}
To meet the condition when testing
if (cache[query] == null)
however, you need to test it like this :
if(typeof cache[query] == 'undefined')
cache is an object and not an array, initialize like cache = {}
Rest of the code seems correct.

Categories