I am working on a prototype that stores products (like a favourite) into localStorage but I am struggling to check to see if an item already exists in localStorage so its not added again.
Where would the best place be to check for a duplicate entry and handle it gracefully?
My sample controller is below:
function dCtrl($scope, $filter) {
$scope.d = [
{id:'1',d_name:'Product 1',colour:'Blue'},
{id:'2',d_name:'Product 2',colour:'Red'},
{id:'3',d_name:'Product 3',colour:'Cream'},
{id:'4',d_name:'Product 4',colour:'White'},
{id:'5',d_name:'Product 5',colour:'Green'},
{id:'6',d_name:'Product 6',colour:'Black'},
{id:'7',d_name:'Product 7',colour:'Purple'},
{id:'8',d_name:'Product 8',colour:'Grey'},
{id:'9',d_name:'Product 9',colour:'Yellow'},
{id:'10',d_name:'Product 10',colour:'Indigo'}
];
$scope.getDetails = function (id, favDresses) {
//get the object of the item clicked
single_object = $filter('filter')($scope.d, {id:id})[0];
// If you want to see the result, check console.log
console.log(single_object);
console.log('ID:' + id + ' - save this object to localStorage');
//set localstorage var
var storage = localStorage.getItem('newfavdresses');
//check to see if the localStorage array is empty (not null)
if(storage != null) {
//if it isnt, parse the string
favDresses = JSON.parse(localStorage.getItem('newfavdresses'));
//push into the array
favDresses.push(single_object);
//set the item in localstorage
localStorage.setItem("newfavdresses",JSON.stringify(favDresses));
} else {
//if the array is null, create it
var favDresses = [];
//and push the item into it
favDresses.push(single_object);
//set the item in local storage
localStorage.setItem("newfavdresses",JSON.stringify(favDresses));
}
}
$scope.clearStorage = function() {
localStorage.clear();
alert('Local Storage Cleared');
}
//get localStorage items
var dresses = localStorage.getItem("newfavdresses");
dresses = JSON.parse(dresses);
console.log(dresses);
}
jsFiddle demo - https://jsfiddle.net/dwhiteside86/Lt7aP/2261/
My suggestion is work with live javascript array stored in service.
You would load this array from localStorage when service initializes or set to empty array if nothing in storage.
Then whenever you update the stored array you always store back the whole thing into localStorage so that the stored version is always a string replica of the live one.
This way you only use getItem() once and then have a simple service method storeLocal() that you call each time you modify array or object in array.
Another thing you might look at is ngStorage that does all of the above for you
Look at https://github.com/grevory/angular-local-storage, I believe it will solve all your issues. This library will bind your scope property to local storage so You'll dont care about how it stores.
Related
This is my code. I am trying since a couple of days to create an Array of Objects, which I will then store in Local Storage. Here is the problem, I need to first Get the existing value from Local Storage.
I then need to add the new data object to the existing array. I then convert it into JSON so that I can store it back in the local storage.
onRegisterSubmit(){
const user = {
a: this.a,
b: this.b,
c: this.c,
id: Date.now()
}
var abc = [];
var get = JSON.parse(localStorage.getItem('user'));
abc = [get];
abc.push(user);
localStorage.setItem('user', JSON.stringify(abc));
console.log(JSON.stringify(abc));
console.log(get);
}
I want the JSON to be an array of objects like this,
[{"hour":1,"minute":21,"ampm":"PM","repeatDays":[],"message":"","todayOrTomorrow":"Tomorrow","isRepeatMode":false,"isEnabled":false,"id":"1493797882440"},{"hour":1,"minute":24,"ampm":"PM","repeatDays":[],"message":"","todayOrTomorrow":"Tomorrow","isRepeatMode":false,"isEnabled":false,"id":"1493797896257"},{"hour":6,"minute":14,"ampm":"PM","repeatDays":[],"message":"","todayOrTomorrow":"Tomorrow","isRepeatMode":false,"isEnabled":false,"id":"1493815470408"}]
This is my JSON.
[[[[[[[{"id":1493820594019},{"id":1493820606448}],{"id":1493820609111}],{"id":1493820610150}],{"id":1493820610553}],{"id":1493820610827}],{"id":1493820611015}],{"id":1493820612018}]
I've been trying for several days and any help will be greatly appreciated.
The issues with that code are:
You're wrapping the result you get in an array, but in theory, you want to already have an array.
You're storing user, not get or abc. (You removed that with an edit.)
To store the array, do what you're doing:
localStorage.setItem("users", JSON.stringify(users));
To get the array:
users = JSON.parse(localStorage.getItem("users") || "[]");
Note how that provides a default (empty array) if getItem returns null because we've never stored our users there.
To add a user to the array:
users.push({id: 1, foo: "bar"});
Example (live on jsFiddle [Stack Snippets don't allow local storage]):
(function() { // Scoping function to avoid creating globals
// Loading
var users = JSON.parse(localStorage.getItem("users") || "[]");
console.log("# of users: " + users.length);
users.forEach(function(user, index) {
console.log("[" + index + "]: " + user.id);
});
// Modifying
var user = {
id: Math.floor(Math.random() * 1000000)
};
users.push(user);
console.log("Added user #" + user.id);
// Saving
localStorage.setItem("users", JSON.stringify(users));
})();
That shows you the list of current users in the console, adding one each time you refresh the page.
Try something like this:-
link https://jsfiddle.net/sureshraina/nLexkyfw/1/
var mydatas = new Array();
mydatas[0] = "data";
mydatas[1] = "data1";
mydatas[2] = "data2";
localStorage["mydatas"] = JSON.stringify(mydatas);
var datas = JSON.parse(localStorage["mydatas"]);
See this post.
You can't store Objects, you have to store a String. So the workaround is to stringify your Object before you store it (for example, you could use change it to a JSON object, store it, and read it again when needed).
I need this solution for my project. its very important for me.
i want to update object value with key and index, from local storage
FOR
my cart application.
(Decrease button for product quantity in cart)
Exmp.
function decreaseQuantity(index) {
var oldQty = localStorage.cart[index].quantity;
var newQty = oldQty - 1;
localStorage.setItem(cart[index].quantity, newQty);
}
You can't store complex object in localStorage, you can store data as string only.
If you want to store the cart object to locaStorage , you need to serialize it as string using JSON.stringify and store it like following.
window.localStorage.setItem('cart', JSON.stringify(cart));
Note: here 'cart' is the key.
To get back, change it and store back, you need to do like following.
var data = window.localStorage.getItem('cart');
if (data != null) {
let cart= JSON.parse(data);
cart[index].quantity = cart[index].quantity -1;
window.localStorage.setItem('cart', JSON.stringify(cart));
}
its worked for me #PSK thanks for your efforts
#adiga I guess I made a logic error. thank you too, for your interest !
Brief
I'm making an Options page for a Chrome Extension. I have multiple fields however I'm unable to store the data for retrieval later, as it keeps storing an empty array (instead of what I'm asking it to store).
Code
//On load
$(function() {
$("#saveBtn").click(saveAll);
});
//Function to save all data
function saveAll() {
var settings = [];
//Go through all inputs with [data-input-settings] attribute
$("[data-input-settings]:not(.ignore)").each(function(e) {
var $t = $(this);
var n = $t.attr("data-input-settings");
//Add this setting key and value to settings array
settings[n] = getVal(n);
});
//Save to storage
chrome.storage.sync.set({
"settings": settings
}, function() {
console.log(settings);
console.log("Saved");
//Output to check (development environment)
chrome.storage.sync.get("settings", function(o) {
console.log(o.settings);
});
});
}
//Function to retrieve value by field name
function getVal(field){
return $("[data-input-settings='"+field+"']").val() || false;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="settings-advanced">
<label><input type="checkbox" data-input-settings="adv-debug">Enable debug mode</label>
<button type="submit" id="saveBtn">Save All</button></div>
</div>
Expected Output to Console (on Save All button click when checkbox is selected):
[adv-debug: "on"]
Saved
[adv-debug: "on"]
Actual Output to Console (on Save All button click when checkbox is selected):
[adv-debug: "on"]
Saved
[]
When calling the following function at any stage, the output to console is "[]" (even when called on pageload):
function retrieveAll() {
chrome.storage.sync.get("settings", function(o) {
console.log(o.settings);
});
}
Question
Why isn't the settings array being saved to the Chrome sync storage, and what changes are needed to make it work?
In this line:
settings[n] = getVal(n);
since n is a string and not a number, you are adding a property to the array settings, not adding values to it. Remember that arrays are objects, too. After that operation, settings is still a zero-length array with another property (in your case avd-debug: "on" ).
You can try to one of these two things:
1) declare settings as an object instead of an array. I.e. change
var settings = [];
for
var settings = {};
2) add key:value pairs to settings array using, for instance, push, like:
settings.push({[n]:getVal(n)});
Context
In a Firebase DB I'm storing "events" and "users". Users can have favorite events, to manage them I only store the event's id in the favorite user's DB location. So to grab favorite events informations, I need to firstable grab the event id and then go to the DB events location, to collect all the datas I need.
Problem
I would like to store in an Array all the favorite events informations (each event would be an Object with inside it : "key" : "value"), to use that Array in my HTML view and print the informations. But it doesn't work the way I coded it... :(
// This ref is too grab favorite event id (in my case only 2) in the user DB location
var refUserFavoris = firebase.database().ref().child("users/"+user.uid+"/events/favoris");
$scope.favorisTmp = $firebaseArray(refUserFavoris);
// This shows one array, with two objects (wich are my two user's favorite events) wich include ids
console.log($scope.favorisTmp);
// This is to load the objects and with the foreEach, grab there ids to use them in the next ref call
$scope.favorisTmp.$loaded().then(function()
{
angular.forEach($scope.favorisTmp, function(favoris)
{
// This shows two lines : the id of each object
console.log(favoris.$id);
// Call a new ref to reach the event informations (in a different location of the DB) using the previous id
firebase.database().ref("events/"+favoris.$id).once('value').then(function(snapshot)
{
// Attempt to store events datas for each id I have (in my case, only two)
snapshot.forEach(function(favorisSnap)
{
var favSnap = favorisSnap.val();
// This shows a lot of "undefined" lines, wich I don't want. I would like two objects, with all informations inside
console.log(favSnap.nbPersonne);
// $scope.favorisF is an Array that I would like to use in a ng-repeat to print all datas for each event
// For now this doesn't show anything
$scope.favorisF = favSnap;
});
// If using favSnap out of the previous function, I got a "favSnap" is undifined error
console.log(favSnap);
});
});
});
<ion-item ng-repeat="f in favorisF" class="item-avatar">
{{f.nbPersonne}}
</ion-item>
EDIT 1 :
I tried a new way to have my data, but a new problem came, how to fill an Array inside a loop ? I've tried "push" and "$add" methods, but no one worked. Any ideas ?
var newFav = [];
var user;
user = firebase.auth().currentUser;
var refUserFavoris = firebase.database().ref().child("users/"+user.uid+"/events/favoris");
$scope.favorisTmp = $firebaseArray(refUserFavoris);
$scope.favorisTmp.$loaded().then(function()
{
angular.forEach($scope.favorisTmp, function(favoris)
{
console.log(favoris.$id);
var refFavoris = firebase.database().ref("events/"+favoris.$id);
refFavoris.on('value', function(snap)
{
//This is where I'm trying to fill "newFav" in each steps of the loop
newFav.push(snap.val());
console.log("Scope newFav vaut :", $scope.newFav);
});
});
});
I think you made a typo here.
var refUserFavoris = firebase.database().ref("events/favoris/"+favoris.$id).once('value')
Thanks a lot Abdel, I fixed my problem :
Here is the solution
$scope.newFav = [];
console.log($scope.newFav);
$scope.favorisTmp.$loaded().then(function()
{
angular.forEach($scope.favorisTmp, function(favoris)
{
console.log(favoris.$id);
var refFavoris = firebase.database().ref("events/"+favoris.$id);
refFavoris.on('value', function(snap)
{
$scope.newFav.push(snap.val());
console.log("Scope newFav vaut :", $scope.newFav);
});
});
});
Here is the localStorage entry I want to use:
Key: file
Value: [{"id":"usethis","somethingelse":"otherstuff"}]
I want to create a var from id in the Value array so I can make an if that says:
var idvalue = ??? (...this is what I need help retrieving...)
if (idvalue == "usethis") { ...do some stuff... } else { ...do something else... }
Try
//read the string value from localStorage
var string = localStorage.getItem('file');
//check if the local storage value exists
if (string) {
//if exists then parse the string back to a array object and assign the first item in the array to a variable item
var file = JSON.parse(string),
item = file[0];
//check whether item exists and its id is usethis
if (item && item.id == "usethis") {} else {}
}
HTML5 Local Storage only handles string key/value pairs. To save your JSON object in Local Storage you will have to stringify it when you save it, and parse the string when you read it back. It is all explained very well in the following StackOverflow question Storing Objects in HTML5 localStorage.