Question when saving data through local storage - javascript

In the process of saving data to local storage.
I want to store objects in a key called 'DB'.
But I get an error saying "list.push is not a function." What's the problem?
let list = JSON.parse(localStorage.getItem('DB'));
const index = number++;
if (!list) {
const arr = [];
arr.push({
todo: text,
index: index
});
localStorage.setItem("DB", JSON.stringify(arr));
} else {
list.push({
todo: text,
index: index
});
console.log(list);
localStorage.setItem("DB", JSON.stringify(list));
}

If you already have something stored in the storage item DB that does not parse to an array, the code will fail. If I run it twice it does what I assume you want it to do, and I get a stringified array with two objects in my localStorage.
I suggest you try again, and if you have problems check what's in your localStorage.
As an aside, your code could be streamlined a little. For example:
let list = JSON.parse(localStorage.getItem('DB'));
// Maybe print out list here, to see what it is immediately after parsing
console.log('list:', list);
const index = number++;
if (!list) {
list = [];
});
list.push({
todo: text,
index: index
});
localStorage.setItem("DB", JSON.stringify(list));

Related

Delete specific string from Local Storage array

I have this code
function deleteElement() {
const myArray = map(listItems, getText);
var elementToDelete =document.getElementById('deleteElement').value;
const index = myArray.findIndex((item) => item.includes(elementToDelete));
if (index > -1) {
// delete and update local storage
console.log("found element and index ", index);
let moment = localStorage.getItem('pelis_guardades');
let deleted = moment.splice(index, 1);
localStorage.setItem('pelis_guardades', JSON.stringify(deleted))
console.log(deleted);
}
}
I have found the index of the element of the array that I want to delete, everything's good, but now I would like to "update" the local storage to delete the item from the index.
I can delete the specific value on the array that loads into the local Storage. Called myArray.
const myArray = map(listItems, getText);
myArray contains the "raw string data" that then gets put on the local Storage via,
localStorage.setItem('things',JSON.stringify(myArray));
How can I delete from the localStorage?
I've tried, the splice method on the local storage but doesn't work!!
Thanks!
try to parsing the moment variable to JSON
using
edit
function deleteElement() {
const myArray = map(listItems, getText);
var elementToDelete =document.getElementById('deleteElement').value;
const index = myArray.findIndex((item) => item.includes(elementToDelete));
if (index > -1) {
// delete and update local storage
console.log("found element and index ", index);
let moment = localStorage.getItem('pelis_guardades');
//try to add this code
let moment_parse = JSON.parse(moment);
let deleted = moment_parse.splice(index, 1);//edit
localStorage.setItem('pelis_guardades', JSON.stringify(deleted))
console.log(deleted);
}
before you splice the moment variable
The problem is that you've made a mistake using Array.splice.
This method mutates the given array.
You don't need the result of the splice operation. Instead you must pass the array as the new value to update the localstorage.
// 1. read value
const moment = JSON.parse(localStorage.getItem('pelis_guardades'))
// 2. mutate given array by removing one element from index.
moment.splice(index, 1);
// 3. write value
localStorage.setItem('pelis_guardades', JSON.stringify(moment))

Replicating MySQL array formatting in Javasript

I have 5 mysql tables that i need a variety of data from in several different scripts that all reference each other using an id's located in 1 or more column.
I need to create a master query that replicates the array structure exactly as it was imported from mysql AND ALSO needs error handling for each field before it writes to an array to determine if it needs to write the value to an array, or write it as null.
So far the script is looking like this:
const items = [];
// Items
for (let i = 0; i < gameItems.length; i++) {
if (gameItems[i].id) {
items.push({ id: gameItems[i].id });
} else {
items.push({ id: null });
}
if (gameItems[i].identifier) {
items.push({ identifier: if (gameItemParams[i].custom_name)
{
items.push({ custom_name: gameItemParams[i].custom_name });
}
else {
items.push({ custom_name: null }); }
}
}
The problem, or my lack of ability to figure out the logic on how to execute the code correctly, is that in order to attach multiple fields of data to the same row in an array the values must be comma separated.
Individual pushes like above add data to the next row instead of the same object which renders the array.length properly useless because there is a new row for every single field so instead of having 1 row with 10 pieces of data attached, i would have 10 rows each with 1 piece of data.
Is there a way to perform error handling for each field i need to call from the tables or is there another way to add data to the same object after a row has already been pushed.
This is how the newly created array must be structured:
https://puu.sh/E7ogn/61c3117d3b.png
This is how the array is currently being structured with individual pushes:
https://puu.sh/E7oh7/422541a70d.png
Maybe if it is possible to break in the middle of an array.push i can then add error handling in the push block but was unable to find if it can be done.
The problem is that you are pushing an object every time. Instead of that, you need to create an object with all of fields and then push it to the array.
Other problem of your code is that you can use an if statement into a assigment statement. You need to use a conditional operator to do that or extract this conditional from the assigment.
const items = [];
// Items
for (let i = 0; i < gameItems.length; i++) {
var object = {};
if (gameItems[i].id) {
object.id = gameItems[i].id;
}
else {
object.id = null;
}
if (gameItems[i].identifier) {
object.identifier = (gameItemParams[i].custom_name) ? items.push({ custom_name: gameItemParams[i].custom_name }); : items.push({ custom_name: null });
}
items.push(object);
}
As per the data mentioned in https://puu.sh/E7oh7/422541a70d.png.
You have data like
gameItems=[{id:0}, {identifier:"master-ball"}, {category_id:34}, {"custom_name":"Master Ball"}];
I suggest that instead of making items as an array, Please create temporary object item and then push it to items.
let items = [];
let item = {
id:null,
identifier: null,
custom_name: null
};
for (let i = 0; i < gameItems.length; i++) {
if (gameItems[i].id !== undefined) {
item.id = gameItems[i].id;
}
if (gameItems[i].identifier !== undefined) {
item.identifier = gameItems[i].identifier;
}
if (gameItems[i].custom_name !== undefined) {
item.custom_name = gameItems[i].custom_name;
}
}
items.push(item);

How to check if a item/value already exists in Local Storage

I am working on a shopping cart application were users can click an Add to Cart button that will then add the specific item to local storage. When the user is adding a product to their shopping cart I need to be able to check to see if that specific item/value/product already exists in local storage. If it does, I need to increase only the count of that item/value/product by 1. If not, I need to add an entirely new item/value/product to local storage with a count of 1.
How can I find if an item already exists in local storage and compare it to the id of the current product that a user is attempting to add to their cart? My first few attempts failed miserably and have yet to find anything online that is helping with this issue. Is there a better way of going about this? Any assistance is appreciated. Even a good link to a good page would be extremely helpful.
Below is the code I have to attempt in checking for if the productid being added matches any of the productids in local storage. Basically if the productId that is being added matches the productId of an item in local storage simply add 1 to the quantity.
var retrieverObject = localStorage.getItem('Products');
var retrieveObject = JSON.parse(retrieverObject);
var data = {};
var productId = currentNode.name;
var product = currentNode;
data.productPrice = product.parentNode.previousSibling.previousSibling.id;
data.productId = productId;
var length = retrieveObject.length;
console.log(length);
for(var i = 0; i<length; i++){
if(retrieveObject[i].productId == data.productId){
var quantity = retrieveObject[i].quantity;
retrieveObject.push({"productPrice": data.productPrice, "productId": data.productId, "quantity": quantity++});
}else{
retrieveObject.push({"productPrice": data.productPrice, "productId": data.productId, "quantity": 1});
}
}
console.log(retrieveObject);
localStorage.setItem('Products', JSON.stringify(retrieveObject));
var retrievedObject = localStorage.getItem('Products');
var obj = JSON.parse(retrieverObject);
var len = obj.length;
console.log(len);
for(var i=0; i<len;i++){
console.log(obj[i]['productPrice']+", "+obj[i]['productId']);
}
}
}
There are a few issues. First, I am not entirely certain that the productId of the retrieved object is being compared to the one that is being added. Secondly, the for(var i = 0; i<length; i++){} definitely does not seem to be doing what was expected and is multiplying the number of items being added by 2. Thirdly, which may relate to the second issue, the retrieveObject.push() is not updating the quantity of the product but is adding an entire new entry to local storage. The given answers did not seem to be working for me before so this is what I have been working on. Any new answers or general help would be great.
PT 2. : So I am having an issue with the first entry into the local storage. Without noting that when there is nothing in local storage and you make a call to get the items in it, it returns null or undefined. So currently I have it set up like this:
if(localStorage.getItem("Products") === null || localStorage.getItem("Products") === undefined){
var data = {};
var productId = currentNode.name;
var product = currentNode;
data.productPrice = product.parentNode.previousSibling.previousSibling.id;
data.productId = productId;
var obj = [];
obj = obj[data.productId] = {
productPrice: data.productPrice,
count: 1
};
console.log(obj);
localStorage.setItem('Products', JSON.stringify(obj));
}
else{
var retrieverObject = localStorage.getItem('Products');
var retrieveObject = JSON.parse(retrieverObject);
var data = {};
var productId = currentNode.name;
var product = currentNode;
data.productPrice = product.parentNode.previousSibling.previousSibling.id;
data.productId = productId;
if(retrieveObject[data.productId]){
retrieveObject[data.productId].count++;
}else{
retrieveObject[data.productId] = {
productPrice: data.productPrice,
count: 1
};
}
console.log(retrieveObject);
localStorage.setItem('Products', JSON.stringify(retrieveObject));
}
This creates a first entry in local storage that looks like this : {"productPrice":"78.34","count":1}, and then when adding others looks like this: {"productPrice":"78.34","count":1,"rJUg4uiGl":{"productPrice":"78.34","count":3}} and works perfectly fine. The issue is getting the first entry to b formatted properly. When I change the code in the first if statement like so:
var obj = [];
obj[data.productId] = {
productPrice: data.productPrice,
count: 1
}
I get an empty [] in local storage but when I console.log the obj it is in the proper format. [rJUg4uiGl: Object]. I have been stuck on this and haven't been able to get it working. Again, any help would be really appreciated.
Once you have your data structure in obj, I would suggest using a dictionary with product IDs as keys.
To add the order or whatever, where you have:
obj.push({"productPrice": data.productPrice, "productId": data.productId});
Use:
if (obj[data.productId]) { // if the entry exists,
// increment the count
obj[data.productId].count++;
} else { // if it doesn't,
// add a new entry with count = 1
obj[data.productId] = {
productPrice: data.productPrice,
count: 1
};
}
Here is a complete function, including localStorage handling:
function addToCart(productID, productPrice) {
// get the current cart, or an empty object if null
var cart = JSON.parse(localStorage.getItem("Products")) || {};
// update the cart by adding an entry or incrementing an existing one
if (cart[productId]) {
cart[productId].count++;
} else {
cart[productId] = {
productPrice, // shorthand for `productPrice: productPrice,`
count: 1
};
}
// put the result back in localStorage
localStorage.setItem("Products", JSON.stringify(cart));
}
The solution above is preferable because you can check for a productId without looping through the whole list. If you really want to keep your current data structure of an array of objects, you could update it like this:
var length = retrieveObject.length;
console.log(length);
for (var i = 0; i < length; i++) {
if (retrieveObject[i].productId == data.productId) {
retrieveObject[i].quantity++; // update the entry in the array
} else {
retrieveObject.push({
productPrice: data.productPrice,
productId: data.productId,
quantity: 1
});
}
}
Note that you shouldn't push a new entry into the array; just update the existing one.
Just use localstorage.getItem; it returns null if the key doesn't already exist.
Assuming you are using localStorage node package you could do
if (localStorage.getItem('Products') !== null) {
localStorage.setItem('Products', JSON.stringify(obj));
}
Here is your reference:
https://www.npmjs.com/package/localStorage
Regards
Update:
Searching within your objet is a different story... so you want to check if the Product id is there then you can search for it using lodash
var _ = require('lodash');
// the rest of your code to get the data.productId set
if (localStorage.getItem('Products') !== null) {
var arrayOfProducts = localStorage.getItem('Products');
var existingProducts = _.filter(arrayOfProducts, function (product) { return product.productId === data.productId });
if (existingProducts.length > 0) {
// product found, do your logic
}
}
Here's lodash info https://www.npmjs.com/package/lodash
The other option is using a dictionary and having the productId as key and then using Object.keys to search for it... I've offered an approach that does not change your json structure.

How to delete a specific string entry out of array

I am trying to delete string out of array but the string is staying there. Any suggestions?
$scope.removeFavorites = function (word) {
debugger;
// retrieve it (Or create a blank array if there isn't any info saved yet),
var favorites = JSON.parse(localStorage.getItem('favoritesInfo')) || [];
for (var i = favorites.length - 1; i >= 0; i--) {
if (favorites[i] === word {
favorites.splice(i, 1);
console.log(favorites[i]);
}
}
//favorites.pop();
// localStorage.setItem('favoritesInfo', JSON.stringify(favorites));
console.log(localStorage.getItem('favoritesInfo'));
}
In the above code the splicing is being done to favorites array which gets the values from the localstorage
var favorites = JSON.parse(localStorage.getItem('favoritesInfo')) || [];
so the value is removed in favorites array but not in the localstorage.
localStorage.getItem('favoritesInfo') still contains the complete set of values.
You have two solutions.
Use the favorites array which is your filtered set of list where
ever needed.
Update the local storage with the favorites array to
keep both in sync.

Javascript search if LocalStorage variable exists

I am programming a chat system. I always make a Localstorage variable when a new chat is opened. Created like this:
localStorage.setItem("chat_"+varemail, data);
Now i want to check how many of them I have so something like:
"chat_"+... count.
How can I do this?
You'd grab the array of keys of the localStorage object, and use Array.filter to grab only the items starting with "chat_":
var length = Object.keys(localStorage).filter(function(key) {
return /^chat_.+/.test(key);
}).length;
Here's a JSFiddle
Try something like this, loop through all items in localStorage and match against your pattern
function getChatCount(){
var chatCount = 0;
for(item in localStorage){
if(item.indexOf('chat_') > -1) chatCount++;
}
return chatCount;
}
Local storage is based on key, value pairs. AFAIK, you wouldn't be able to retrieve all values with a certain prefix.
One potential solution would be to store an object that contains these. Based on your needs you could store the objects in an array or object and then retrieve the entire set and find the count.
For example:
var chats = { count: 0 };
chats["chat_"+varemail] = data;
chats.count += 1;
localStorage.setItem('chats', data);
Then if you want a count, you would retrieve the object:
var chats = localStorage.getItem('chats');
//chats.count would give you the count.
Although, this would mean you have to manually maintain the count variable when adding or removing data. If you don't need the indexing ability, you could add the chats to an array and store that.
EDIT: It is possible to find properties with a certain prefix, as seen in an answer to this question.
I would offer to convert to localStorage.setItem("chat", JSON.stringify(stack)), where stack is an array of chat objects. This way, you have access to an array of chats which you can count, search within, etc.
Something like:
var chatStore =
{
Count: function () {
var stack = JSON.parse(localStorage.getItem("chats"));
if (!stack)
return 0;
return stack.length;
},
Peek: function () {
var stack = JSON.parse(localStorage.getItem("chats"));
if (!stack)
stack = [];
if (stack.length > 0)
return stack.pop();
},
Push: function (token) {
var stack = JSON.parse(localStorage.getItem("chats"));
if (!stack)
stack = [];
stack.push(token);
localStorage.setItem("chats", JSON.stringify(stack));
},
// more methods to you might wish to implement: search, insert, etc.
}
// usage:
chatStore.Push(chatObject); // sets the last chat
chatStore.Peek(); // gets the last chat

Categories

Resources