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.
Related
I'm relatively new to Web Development and deploying my first Web App (To-Do-List) right now, you can have a look at it https://peaceful-stream-48694.herokuapp.com/.
Now I want to add HTML local storage to save the To-Do's, and i get thrown a type error (cannot read property of nullof my To-Do's error) when initializing the Website.
I know that I either have to set the array to zero when there is no items from the storage, or load them into the array in case there is (which already worked), however i can't figure out how to do it when there is nothing in storage.
I guess it is a matter of scope, but I just don't know how to solve it. Here is the piece of code that stores and loads the data:
function saveList() {
let str = JSON.stringify(toDoList);
localStorage.setItem("todoList", str );
}
function loadList() {
if (toDoList == null) {
toDoList = [];
} else {
let str = localStorage.getItem("todoList")
toDoList = JSON.parse(str);
displayList()
}
}
function displayList() {
if (toDoList != null) {
for(i=0; i < toDoList.length; i++) {
htmlInsert ='<div id="' + toDoList[i].id + '" class="newItem"> <input type="checkbox"> <p>' + toDoList[i].toDo +'</p> <button type="button" class="deleteButton">DELETE</button></div>';
list = document.getElementById("itemsList");
list.insertAdjacentHTML("beforeend", htmlInsert);
SetupEventListener();
}
}
}
loadList()
The To-Do array is globally defined at the beginning:
let toDoList = [];
I appreciate any help.
Thanks a lot and sorry if this is messy, didn't know how to make this clearer.
Cheers
You initialize let toDoList = [], then the first thing you do (in loadList()) is test if (toDoList == null). This condition will never be met.
I think your loadList function should look like this :
function loadList() {
let str = localStorage.getItem("todoList"); // can be null
toDoList = str ? JSON.parse(str) : [];
displayList();
}
Then in displayList() you can remove if (toDoList != null) because this condition will always be met (todoList will never be null because it is always initialized as an array)
I'm using an object with information for a bookmark tagging system that needs to persist across Chrome sessions, so I'm trying to save it to local storage and update it whenever a new bookmark is created.
When I create a new bookmark, I fire a function to see if there are now any other bookmarks with the same tag as the new bookmark. This organizes bookmarks into "tag groups" that function kind of like dynamic folders.
When I set the storage object, the object being stored has all the data I'd expect. However, as soon as I get the same object out of storage, one of the nested objects mysteriously turns to null. See console output: the top object is just before the set call in function updateStorage. The bottom is what I get back when I "get" that object from storage. Notice the tagGroups bookmarks are now null. The bookmarks themselves are still there, it's only in the tag group object that they disappear. I've spent a full day and night messing around with this trying to get it to work.
Here is the model code. I included everything for context, but the most relevant pieces are the createNewBookmark, updatePrimaryTreeWithTagGroups, and updateStorage methods.
UPDATE: I've edited the code to make all the changes to the bookmarks tree before setting/getting anything from storage, then making a final call to update storage with the resulting object. I'm literally storing one thing, one time, and getting back another whenever I try to retrieve.
function PrimaryBookmarksTree(){
chrome.storage.sync.get(null, this.findOrCreate.bind(this));
}
PrimaryBookmarksTree.prototype.findOrCreate = function(result){
if (result.bookmarksTree != undefined){
this.bookmarks = result.bookmarksTree.bookmarks;
this.title = result.bookmarksTree.title;
this.tagGroups = result.bookmarksTree.tagGroups;
console.log(this);
} else {
this.bookmarks = [];
this.title = "Marinade Bookmarks";
this.tagGroups = [];
chrome.storage.sync.set({"bookmarksTree": this}, function(){console.log("New tree created!")});
console.log(this);
}
}
function Bookmark(name, tags, url){
this.name = name;
this.tags = tags;
this.url = url;
this.dateCreated = this.date();
}
function TagGroup(tag){
this.bookmarks = [];
this.tag = tag;
}
//called by controller when user tags a new bookmark via the extension
PrimaryBookmarksTree.prototype.createNewBookmark = function(name, tags, url){
var newBookmark = new Bookmark(name, tags, url);
this.bookmarks.push(newBookmark);
this.tagGroups = this.updatePrimaryTreeWithTagGroups();
this.updateStorage(this);
}
PrimaryBookmarksTree.prototype.updatePrimaryTreeWithTagGroups = function(){
var tagsForGrouping = this.getTagsWithMultipleBookmarks(this.bookmarks);
for(j=0;j<tagsForGrouping.length;j++){
this.tagGroups.push(this.buildTagGroup(tagsForGrouping[j]));
}
return this.tagGroups;
}
PrimaryBookmarksTree.prototype.getTagsWithMultipleBookmarks = function(bookmarks){
var tagsToCheck = this.pluck(bookmarks, "tags");
var tagCounts = tagsToCheck.reduce(function (obj, curr){
if (typeof obj[curr] == 'undefined') {
obj[curr] = 1;
} else {
obj[curr] += 1;
}
return obj;
}, {});
var tagGroups = this.filter(tagCounts, function(x){return x > 1});
return tagGroups;
}
PrimaryBookmarksTree.prototype.buildTagGroup = function(tag){
tagGroup = new TagGroup(tag);
for(i=0;i<this.bookmarks.length;i++){
if(this.bookmarks[i].tags[0] == tag){
tagGroup.bookmarks.push(this.bookmarks[i]);
}
}
if (tagGroup.bookmarks.length != 0){
return tagGroup;
}
}
PrimaryBookmarksTree.prototype.updateStorage = function(updatedTree){
console.log(JSON.stringify(updatedTree));
chrome.storage.sync.set({"bookmarksTree": updatedTree}, function(){console.log("final storage complete")});
}
You are always setting this.tagGroups to undefined when you retrieve your data from the sync storage:
PrimaryBookmarksTree.prototype.findOrCreate = function(result){
if (result.bookmarksTree != undefined){
this.bookmarks = result.bookmarksTree.bookmarks;
this.title = result.bookmarksTree.title;
this.tagGroups = result.tagGroups; // should be result.bookmarksTree.tagGroups
console.log(this);
}
}
I have a bug in my code that only saves the last object in an array upon reload. I have a feeling that my addAccount() function is not saving or inserting data correctly. Everything else works correctly. In my console, it shows that the data is being inserted into the array, but when I refresh I only get the last object saved.
I'm not sure what to do.
// The list of accounts array.
var accountsArray = [];
function addAccount() {
// Take fields and put user data into varables.
var accountName = document.getElementById('accountName').value;
var accountBalance = document.getElementById('accountBalance').value;
var accountType = document.getElementById("accountType");
var accountTypeSelected = accountType.options[accountType.selectedIndex].text;
var accountCurrency = document.getElementById("accountCurrency");
var accountCurrencySelected = accountCurrency.options[accountCurrency.selectedIndex].text;
var temporaryObject = {
'accountName': accountName,
'accountBalance': accountBalance,
'accountTypeSelected': accountTypeSelected,
'accountCurrencySelected': accountCurrencySelected
};
accountsArray.push(temporaryObject);
console.log(accountsArray);
saveAccountData();
showAccountsArray();
}
function saveAccountData() {
localStorage.setItem('accountsArray', JSON.stringify(accountsArray));
}
function showAccountsArray() {
//var accountsLocalStorage = JSON.parse(localStorage['accountsArray']);
if (localStorage.getItem("accountsArray") === null) {
document.getElementById("getStarted").style.visibility="visible";
document.getElementById("balanceToolbarName").style.visibility="hidden";
document.getElementById("accountsMainList").style.visibility="hidden";
} else {
var accountsLocalStorage = JSON.parse(localStorage['accountsArray']);
console.log(accountsLocalStorage);
var accountInfo = '';
var i = 0;
while (i < accountsLocalStorage.length) {
accountInfo += '<li class="swipeout"><div class="swipeout-content item-content"><div class="item-inner"><div class="item-title">' + accountsLocalStorage[i].accountName + '</div><div class="item-after">$' + accountsLocalStorage[i].accountBalance + '</div></div></div><div class="swipeout-actions-left"><a href="#" class="action1">Clear</div><div class="swipeout-actions-right">Delete</div></a></li>';
document.getElementById("accountsList").innerHTML = accountInfo;
i++;
}
document.getElementById("getStarted").style.visibility="hidden";
document.getElementById("balanceToolbarName").style.visibility="visible";
document.getElementById("accountsMainList").style.visibility="visible";
}
}
*
all of your functions work correctly as tested by the link you've provided. When the page loads it successfully retrieves the data (if any) from the local storage and displays on the page. However, the global array variable accountsArray is populated with data retrieved from the local storage.
You need to repopulate the global array otherwise when you call saveAccountData it will save whatever the array holds which indeed overrides whatever you had in the local storage. To fix it, simply add add this code block...
$(function(){
var data = localStorage.getItem("accountsArray");
if(data != null)
accountsArray = JSON.parse(localStorage.getItem("accountsArray"));
});
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.
In localStorage I have a object records. It has many fields
records[recordId] and I want to be able to delete these entries. Below is my delete function but it does not work. All the records remain attached to the records object in local storage. Not sure what is wrong as I am deleting in what looks like the correct manner. When I print the records object all the records are still there along with their keys????
function deleteLocalRecord(recordId) {
var records = localStorage.getItem('records');
var theRecords;
if (supports_html5_storage()) {
if (records == null) {
theRecords = {};
} else {
// parse the records
theRecords = JSON.parse(records);
}
theRecords[recordId] = ''; // set the record to empty string.
delete theRecords[recordId]; // delete the record
// reset the records object in local storage after change
localStorage.setItem('records', JSON.stringify(theRecords));
}
}
function supports_html5_storage()
{
try
{
return 'localStorage' in window && window['localStorage'] !== null;
}
catch (e)
{
return false;
}
}
Live demo
function deleteLocalRecord(recordId) {
if (localStorageEnabled()) {
var records = localStorage.getItem('records'),
theRecords = JSON.parse(records) || {};
print(JSON.stringify(theRecords)); // before
delete theRecords[recordId]; // delete
print(JSON.stringify(theRecords)); // after
localStorage.setItem('records', JSON.stringify(theRecords));
print(localStorage.getItem("records"));
}
}
var records = {
"test": "test",
"stuff": "stuff"
};
localStorage.setItem("records", JSON.stringify(records));
deleteLocalRecord("test");
function print(x) {
document.body.innerHTML += "<p>" + x + "</p>";
};
function localStorageEnabled() {
return typeof window["localStorage"] !== "undefined";
};