After I refresh my browser to retrieve data from localstorage and update that data, it's not updated. But when I add new items and update it, it is updating. What's seems to be the problem here?
//----- update existing item's subtotal in localstorage
changeSubtotalOfExisting(qty ) {
let updateQty = JSON.parse(localStorage.getItem('cart_items'));
updateQty['qtyTotal'] = qty;
localStorage.setItem("cart_items", JSON.stringify(updateQty));
console.log('updateQty: ', updateQty );
}
Here's a stackblitz sample:
https://stackblitz.com/edit/angular-ivy-i8kpub?file=src/app/app.component.ts
There were several problems with your implementation. Failing to save to local storage was only one of them. I ended up rewriting a lot of it, and actually simplifying considerably. I apologize if this was not your intention in your question. Here is the resulting project: https://stackblitz.com/edit/angular-cart-local-storage. You can compare the 2 projects.
I'm listing here some key issues:
Accessing local storage should be done only from the service, not from the component. The service is in charge of saving and retrieving data. The component is in charge of interacting with the user.
You saved to local storage the wrong objects (and maybe this is the answer to your original question). Local storage should store the cart (a list of items). Here for example you're trying to save to local storage as if it stores only one item at a time:
updateQty['qtyTotal'] = qty;
localStorage.setItem("cart_items", JSON.stringify(updateQty));
Your event handlers are called with the wrong arguments. You need to call them with the item as an argument, not the HTML element. Instead of changeSubtotal($event.target, addedItem.variationCost,i) I call changeSubtotal(item ,i)
You did not prevent the user from adding the same item to the cart multiple times.
The initial quantity of an item you add to the cart should be 1 and not 0, as you set the minimum of the quantity control to 1
Related
Hello I'm making a comment section on my website but I don't want to fetch all of the comments from my database when someone refreshes the page I want to solve this problem by storing comments in the array but when I use
export const comments = writable(localStorage.getItem("comments") || []);
it doesn't create an array in my local storage is there even a way to store an array in local storage with svelte or should I handle this problem differently?
If you want to store something in localstorage
user:
localstorage.setItem('comments', JSON.stringify(arr_of_cmnts);
Now, let's assume when your page opens you check if your localstorage has comments by using something like:
//In svelte
let arr_of_cmnts = [];
export const comments = writable(localStorage.getItem('comments')|| JSON.stringify(arr_of_cmnts));
//js **normally**
const cmnts = JSON.parse(localstorage.getItem('comments'));
if(cmnts && cmnts.length > 0)
//use this array
else
//call server to get comnts and store them in localstorage
In the if block how do you know if comments in localstorage are the latest???
Maybe someone has put a new comment from the last time you visited.
There maybe some solutions to this, like you inquiring db for latest comments timestamp and then checking whether the stored comments are stale or not.
Another approach of the issue (not having to query your db always) is to use a Cache (redis maybe), to serve comments, and whenever someone writes a new comment, along with updating db you can update your cache as well.
This makes read request faster.
I'm in the middle of creating a simple tv shows tracker (which ones I have seen/watching at this moment) and as I don't backend myself, I decided to store all the data in local storage.
Right now I'm able to store all the shows in the local storage with no problem. The problem occurs when I need to update data in local storage (to give you a specific example - please look at the screen below):
screenshot of my list with local storage shown
As you can see I have those buttons to adjust the number of show's seasons and episodes (they work just fine).
But I have no idea how to store that updated value and that value only in local storage.
Down below you can find the code that reads data from local storage and use them to create list:
function readFromMemory(){
const data = JSON.parse(localStorage.getItem('seriale'));
data.forEach(element => {
serialeMemory.push(element);
let serialInMemory = new SerialeList(element.pos, element.img, element.name, element.score, element.userEpisodes, element.episodes,element.userSeasons, element.seasons, element.status, element.id);
serialInMemory.inject(); //Creates list from class
serialInMemory.episodeUpDown(); //Gives functionality to episodes buttons
serialInMemory.seasonUpDown(); //Give functionality to seasons buttons
});
deleteSerialRow(); //method to delete the whole row from list and from local storage
}
I know how to filter out to show only what I want by using Array.prototype.filter method. But I don't know how to push only that row into localstorage.
I would very gladly appreciate any insight.
Thank you.
Well, since you only use one key („seriale”), there's no other way as to deserialise it, modify the object accordingly (e.g. using Array.prototype.splice), serialise it again and call localStorage.setItem with the same key and the updated and serialised object.
To be honest I kinda solved it myself.
Here's the method that works:
updateSeasons(id, changeValue){
const data = JSON.parse(localStorage.getItem('seriale'));
const filter = data.filter(element => element.id === id);
filter[0].userSeasons = changeValue;
for(let i = 0; i< serialeMemory.length; i++){
if(serialeMemory[i].id === filter[0].id) serialeMemory[i].userSeasons = changeValue;
}
localStorage.setItem('seriale', JSON.stringify(serialeMemory));
}
I've used the very same array I have kept pushing during the DOMLoad event and it works just fine.
But yeah, I probably should have attach a key to every single show, but I think I'm fine with my solution. Thank you anyway!
I am trying to build a shopping cart by storing user selected product data in local storage and then populate a shopping cart by retrieving product data from local storage. i use the code below to store product data to local storage when the add to cart button is clicked;
$('#addtocart').on('click', function(e) {
var qty = document.getElementById("p-qty").value;
var li = $(this).parent();
var product = {};
product.id = productid;
product.name = document.getElementById("nomenclature").value;
product.price = document.getElementById("productprice").value;
product.quantity = qty;
addToCart(product);
});
function addToCart(product) {
// Retrieve the cart object from local storage
if (localStorage && localStorage.getItem('cart')) {
var cart = JSON.parse(localStorage.getItem('cart'));
cart.products.push(product);
localStorage.setItem('cart', JSON.stringify(cart));
}
window.location = "html/cart.html"
}
and I use this to retrieve stored data in cart.html page
var cart = localStorage.getItem("cart")
console.log("This is what is in mycart", cart)
This works and the product data were successfully retrieved. The problem I'm having is that I want to be able to store product data for more than 1 products unfortunately, only one product data is always available even when multiple items were added to cart. it appears as cart.products.push(product) is replacing existing product with the newly clicked product.
I discovered that the problem I'm having is that whenever the browser is refreshed the array is cleared and starts with an empty array. I want user to be able to add multiple items which will require them going back from product page to listing page.
What am I doing wrong and how can I implement adding more than 1 products and their data to local storage?
First of all, your condition localStorage && localStorage.getItem('cart') fails on the first add, and, since the cart never gets added anywhere else (seemingly), this condition will always fail and nothing will ever be stored there.
Your code should be more like:
function addToCart(product) {
if (localStorage) {
var json = localStorage.getItem('cart') || '{"products": []}';
var cart = JSON.parse(json);
cart.products.push(product);
localStorage.setItem('cart', JSON.stringify(cart));
}
window.location = "html/cart.html"
}
Instead of using local storage, try to use IndexedDB. Because localStorage is useful for storing smaller amounts of data, it is less useful for storing larger amounts of structured data. So if you want to store significant amounts of structured data such as, in your case, storing product details, indexedDB is a better choice.
Another advantage of using IndexedDB is that you can do high performance searches using indexes.
It also provides both a synchronous and an asynchronous API. As you can see, in practice, however, all current implementations are asynchronous, and requests will not block the user interface from loading. IndexedDB is what you should choose.
for your reference:
https://www.w3.org/TR/IndexedDB-2/
https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API
So I am working on \app\code\core\Mage\Checkout\Helper\Data.php at the moment. And I am trying to call a variable but it doesn't seem It's working.
UPDATE 1
I have been able to pass the variable by method like this, but I need to declare the product ID manually, is there anything allows the method get the product id base on the product i added into cart?
$_productId = Mage::registry('current_product')->getId();
is not working in my case.
My test as below:
public function formatPrice($price)
{
$_productId = 463089; // need to call the current product by the enter the ID manually
$_product = Mage::getModel('catalog/product')->load($_productId);
$oldPrice = $_product->getFinalPrice(); //should be the original product price
return $this->getQuote()->getStore()->formatPrice($oldPrice);
}
The result after i refresh my page :
everything turns to 670
Many thanks
You're "working on \app\code\core\Mage\Checkout\Helper\Data.php", which is the first problem. Never edit the Magento core.
Assuming you move this to your own event observer to modify the data, you are loading the product ID with a static variable set to 463089, then doing nothing to calculate a new price, then displaying the products price.
From your code it makes perfect sense that the price would always remain the same since you are manually setting which product to pull the price from.
It could be a number of reasons why the quantity of the item is not changing the price. It might have something to do with other core edits you may have made.
I wrote a bookmarklet that retrieves information from a page and stores it in JSON format in local storage (converting it to a string first, of course).
I would like a web app I am writing to be able to process this data, on the fly, preferably as it gets saved to the localStorage.
Right now i can change the item in LS via the console and refresh the page and the new data appears but I would like it to be live and seamless.
Any advice on how to go about this? I found several localStorage modules for angularJS and I tried them but they don't seem to allow me to retrieve from LS if the data is already there in LS.
In response to answer:
$scope.$watch(
function(){
return $window.localStorage.getItem('TestData');
},
function(newValueInStorage){
$scope.testingLS = newValueInStorage;
}
)
I tried this and I still get the data displayed by just doing a {{ testingLS }} in the view template but when I go and change the TestData key in local storage via the console it doesn't update instantly. (for now, I am just testing it without the bookmarklet with just a simple string inside TestData
There is few ways to do it
One of will be to populate correct model on scope when saving to localStorage
The other that I can think of at this moment is to setup watcher
$watch(
function(){
return localstorage object
},
function(newValueInStorage){
$scope.modelFromLS = JSON.parse(newValueInsStorage)
}
)
---edit---
as per James comment you need something that will handle the fact that data has changed in different tab and $digest process need to run for watch to be recalculated
http://plnkr.co/edit/zlS3wL65meBeA8KkV5KH?p=preview
window.addEventListener('focus', function(){
console.log('focus')
$scope.$digest()
})