Reputation: 247
I have a dynamic listview that displays various offers for stores. I want the user to be able to save these offers when they select from the listview in order to produce a saved offers feature using localStorage.
I have managed to reach a point where you can save 1 offer from selecting the offer in the listview.
On selection of the listview row it takes the data attributes from that particular selection and populates an array which is then passed to localStorage.
JS
$("#offers ul").on("click", ">li", function(event, ui) {
var offertitle = $(this).closest('li').attr('data-offer-title');
var offerdesc = $(this).closest('li').attr('data-offer-desc');
var offerexpiry = $(this).closest('li').attr('data-offer-expiry');
if (offerObject === null) {
offerObject = [];
}
var offerObject= {"offer":[
{
'offertitle': offertitle,
'offerdesc': offerdesc,
'offerexpiry': offerexpiry
}
]};
var offers = localStorage.setItem('offerObject', JSON.stringify(offerObject));
offers.push(offerObject);
});
var retrievedOffers = JSON.parse(localStorage.getItem('offerObject'));
var output2='';
for (var i in retrievedOffers.offer) {
output2+="<li>" + retrievedOffers.offer[i].offertitle + " " + retrievedOffers.offer[i].offerdesc + " " + retrievedOffers.offer[i].offerexpiry+"</li>";
}
$('#savedofferlist').html(output2).listview().listview('refresh');
I am now trying to push further offers of the listview into the offerObject variable in order to produce a listview of saved offers based on the user's selections using localStorage.
I get JS error "cannot read property push of undefined" when I try to make a selection from the listview. Even though the error is present, it still displays the 1 selection from the list I have made.
Would I have to break down the .push(offerObject) rather than pushing the whole variable?
Any help would be appreciated.
Upvotes: 0
Views: 4587
Reputation: 63580
The setItem()
method on localStorage
has a void
return type (docs) so you are trying to use push()
on "nothing".
You'll need to fetch the list from local storage (either before or after your insertion)... and "append" to it locally, if you fetched it before your "set".
//Option 1: set then fetch
localStorage.setItem('offerObject', JSON.stringify(offerObject));
var offers = JSON.parse(localStorage.getItem('offerObject'));
//Option 2: fetch, set then append
var offers = JSON.parse(localStorage.getItem('offerObject'));
localStorage.setItem('offerObject', JSON.stringify(offerObject));
//append the current object to the previously fetched list
offers.push(offerObject);
Update
Looking closer at the code it appears that your JSON structure doesn't match what I think you're hoping for. Fundamentally you want your stored object "offerObject" to actually be an Array (list), not an Object (e.g. map).
As a result you will always need to fetch the current list from local storage first, append to it, then set it back.
I've altered your code to better reflect what I think you're trying to do (and here's a JSFiddle for it you can try out:
//get your values (I hard coded this for my test)
var offertitle = "This is the offer title id:[" + new Date().getTime() + "]";
var offerdesc = "This is the offer description";
var offerexpiry = "This is the offer expiry " + new Date();
//create your offer object (I just made this a simple 3 key/value pair)
var offer = {
"offertitle": offertitle,
"offerdesc": offerdesc,
"offerexpiry": offerexpiry
};
var offers = [];//initialize an empty array for all of the offers
//get the current list of offers (if any)
var existingOffers = localStorage.getItem('offers');
if(existingOffers != null){
offers = JSON.parse(existingOffers);
}
//append the new item
offers.push(offer);
//reset the local storage
localStorage.setItem('offers', JSON.stringify(offers));
console.log('Offers: ' + offers.length + '\n\n' + JSON.stringify(offers));
Upvotes: 1