Append objects in local storage - javascript

I store objects in local storage with the following:
localStorage.setItem('obj', JSON.stringify(obj));
I want to add multiple instances of obj every one second, giving a time key. How can I append obj instead of change it every time?

var oldItems = JSON.parse(localStorage.getItem('itemsArray')) || [];
var newItem =
{
'product-name': itemContainer.find('h2.product-name a').text(),
'product-image': itemContainer.find('div.product-image img').attr('src'),
'product-price': itemContainer.find('span.product-price').text()
};
oldItems.push(newItem);
localStorage.setItem('itemsArray', JSON.stringify(oldItems));
You may also want to consider using an object instead of an array and use the product name as the key. This will prevent duplicate entries showing up in LocalStorage.

Basically you have to retrieve the object, add your value and then write it back to localStorage.
var obj = JSON.parse( localStorage.getItem('obj') ) || {};
obj[ timestamp ] = 'newvalue';
localStorage.setItem('obj', JSON.stringify(obj));

There are two options:
Instead of storing the object store a list/map of objects, then to add an element just first do the getItem, then push/set the new element, then use setItem.
Store the objects using the date as the key (e.g. localStorage.setItem('obj:' + x.time, x)) and the use for (x in localStorage) {...} to find all the keys.

function store()
{
var person=new Object();
str = [str stringByReplacingOccurrencesOfString:#" " withString:#"%20"];
person.firstname="John";
person.lastname="Doe";
person.age=50;
person.eyecolor="blue";
localStorage.setObj("temp", person);
var obj=localStorage.getObj("temp");
for(var i in obj)
alert(i+"--"+obj[i]);
}
Storage.prototype.setObj = function(key, obj) {
return this.setItem(key, JSON.stringify(obj))
}
Storage.prototype.getObj = function(key) {
return JSON.parse(this.getItem(key))
}

Related

how to insert new object in node js array if key not exist

I want to create data structure like that.
Var ans =[{"b":[1,2]},{"g":[100,2]}]
I want to create a new object within list if key not exists in list ans.
Else if key exists in one object of ans list then I want to add new values into the object of ans list
For Example:
Example 1) new data c:{2000}
then
Var ans =[{"b":[1,2]},{"g":[100,2]},{c:[2000]}]
Example 2) new data g:{50}
then
Var ans =[{"b":[1,2]},{"g":[100,2,500]},{c:[2000]}]
I am a beginner in node js, understand array, object concept, but not getting exact logic!
Thanks!
You can try following:
Logic
Filter array based on key
Check if object with mentioned key exists or not.
If yes, push value to this array.
If not, create a dummy object and push this object to original array.
Correction, when you do .push({key: value}), key will be considered as string.
Alternates
If you are using ES6, .push({ [key] : value })
Create a dummy object var o = {}. Set key and value to it o[key] = value and push this object.
Optimisations
Instead of setting value like obj[key] = value, since we will be operating on arrays, try obj[key] = [].concat(value). This will enable you to pass value as number or array of values.
Instead of checking the existence of value in .filter, try Array.isArray to check if value exists and is of type array.
Custom function
function checkAndPush(array, key, value) {
var filteredList = array.filter(function(o) {
return Array.isArray(o[key]);
});
filteredList.length > 0 ? filteredList[0][key].push(value) : array.push({
[key]: [].concat(value)
});
return array;
}
var ans =[{"b":[1,2]},{"g":[100,2]}]
console.log(checkAndPush(ans, "c", [2,3]))
console.log(checkAndPush(ans, "c", 4));
Prototype function
Array.prototype.checkAndPush = function(key, value) {
var filteredList = this.filter(function(o) {
return Array.isArray(o[key]);
});
var dummy = {}
dummy[key] = [].concat(value)
filteredList.length > 0 ? filteredList[0][key].push(value) : this.push(dummy);
// or ES6: this.push({ [key]: [].concat(value) })
return this;
}
var ans =[{"b":[1,2]},{"g":[100,2]}]
console.log(ans.checkAndPush("c", [2,3]))
console.log(ans.checkAndPush("c", 4));
If you are dealing with objects as your values
ans[key] = ans[key] || []
ans[key].push(value)
Note, this works because your values will be an array. If they could be primatives then you would use hasOwnProperty to check.
if (ans.hasOwnProperty(key)) {
// Add this to your key somehow
} else {
// initialize the key with your value
}
Node.js is nothing but a library built on javascript. You can do anything using javascript type of progmming. However push and pop method should be able to help you to deal with nodejs array.
ans[key].push(value)

JS access an array with in an object

I have a variable holding a string of validated JSON. The JSON is a set of strings each with a value of an array. I'd like to access the string and each array value.
var json_string = {"div-1":["div-1A", "div-1B"], "div-2":["div-2A", "div-2B"]};
//Run some code to get the following result:
console.log("div-1" has "div-1A");
console.log("div-1" has "div-1B");
console.log("div-2" has "div-2A");
console.log("div-2" has "div-2B");
I have tried a bunch of different things but nothing seems to work right. Additionally, I get a weird functionality. If I do the following:
console.log(json_string["div-1"]);
I randomly get the following results for each page refresh :
div-1A //initial load
div-1C //refresh 1
div-1A //refresh 2
div-1B //etc
div-1A //etc
Any ideas how I can get what I am after?
You can first retrieve the values from keys and then use forEach to get their value
var json_string = {"div-1":["div-1A", "div-1B"],
"div-2":["div-2A", "div-2B"]
};
for(var key in json_string){
var _getValue = json_string[key]
if(_getValue.constructor===Array){ // Checking if it is an array
_getValue.forEach(function(item){
document.write('<pre>'+item+'</pre>')
})
}
JSFIDDLE
It'll be something like this if I understand correctly. You have to traverse through each property and take the array property value against that key.
for (key in json_string) {
var arr = json_string[key];
arr.forEach(function(item) {
console.log(key + ' has ' + item);
});
}
Use Object.keys() for getting all object keys and Array#forEach for iterating over array.
var json_string = {
"div-1": ["div-1A", "div-1B"],
"div-2": ["div-2A", "div-2B"]
};
// Get all object keys and iterate over them
Object.keys(json_string).forEach(function(key) {
// Get inner array using key and iterate
json_string[key].forEach(function(el) {
console.log(key + ' has ' + el)
});
});
For older browser check polyfill option for Object.keys method and forEach method.
It looks like your json_string is actually a JSON object (there's a difference). That said, keys within an object do not follow any sort/ordering. You will need to sort your keys before your output:
var obj = {
"div-1": ["div-1A", "div-1B"],
"div-2": ["div-2A", "div-2B"]
};
Object.keys( obj ).sort().forEach( key =>
obj[ key ].sort().forEach( val =>
console.log( [key,'has',val].join(' ') )
)
);
Of course you could also write your own function to output values for a specific key. Below adds a prototype function to Object, which is just an example (prototyping is generally not recommended):
Object.prototype.valuesFor = function(key){
this[key].sort().forEach( val =>
console.log( [key,'has',val].join(' ') )
)
return this[key];
};
var obj = {
"div-1": ["div-1A", "div-1B"],
"div-2": ["div-2A", "div-2B"]
};
obj.valuesFor('div-1')

Merging 2 arrays in local storage in javascript

I am trying to append an array of objects(new) to the local storage which already has some array of objects(previous) built in. Specifically, I want to merge these 2 arrays (previous and new) in the local storage.
Have tried the below code :
function appendToStorage(name, data)
{
var old = localStorage.getItem(name);
if(old === null)
old = "";
localStorage.setItem(name, old.concat(data));
}
appendToStorage('ObjAry', JSON.stringify(objectIdArray));
And this is the output that I am getting :
["IrGszUBa0F","l366vn6mPa","2qn7JUoRwg","s2fZa0mXnb","WIaXLwmXRa"]["ZKHtnHoHgH","rtbI1sDfPm","U1eVDi9bNM","tUGNCl6hNl","lkq6tswVsZ"]
All I want is that, the second array should append to the first array so the output becomes :
["IrGszUBa0F","l366vn6mPa","2qn7JUoRwg","s2fZa0mXnb","WIaXLwmXRa","ZKHtnHoHgH","rtbI1sDfPm","U1eVDi9bNM","tUGNCl6hNl","lkq6tswVsZ"]
Can anyone guide me on what I am doing wrong ?
You are pretty close, there are just three small mistakes:
You are stringifying the array before concatenating it (so you are attaching a string to an array).
The default value for old is a string, which should probably be an array?
In order to use the array from localstorage, you need to parse it again using JSON.parse.
The resulting code would then be:
function appendToStorage(name, data)
{
var old = localStorage.getItem(name);
if(old == null) {
old = [];
} else {
old = JSON.parse(old);
}
localStorage.setItem(name, JSON.stringify(old.concat(data)));
}
appendToStorage('ObjAry', objectIdArray);
If your local storage entry could contain other values as well, you could add a try ... catch block to your code to make sure that JSON.parse doesn't blow up if it fails to parse the value:
function appendToStorage(name, data)
{
var old = localStorage.getItem(name);
try {
old = JSON.parse(old);
} catch(e) {
old = [];
}
localStorage.setItem(name, JSON.stringify(old.concat(data)));
}
appendToStorage('ObjAry', objectIdArray);
You're concatenating the whole object returning from
JSON.stringify(objectIdArray)
Try
appendToStorage('ObjAry', objectIdArray);
LocalStorage stores a string values by a string key. To store arrays/objects as string we serialize them into JSON. So you need to parse JSON after getItem, merge parsed value with new portion of data, convert merged object to JSON and pass it to setItem.
function appendToStorage(name, data) {
var old = localStorage.getItem(name) || '[]';
var oldObject = JSON.parse(old) || [];
var merged = oldObject.concat(data);
localStorage.setItem(name, JSON.stringify(merged));
}
appendToStorage('ObjAry', objectIdArray);

Most efficient way to remove a list of values from a javascript object by keyname

I need to find the most efficient way to remove values from a arbitrarily nested javascript object based on a list of 'keys-to-remove'. i.e.
var obj = {a:1, b:2, c:{d:1, e:1}};
var ignoreList = ["a","e"] (could also be ['a', 'c.e'])
removeIgnoredValues(obj, ignoreList) => {b:2, c:{d:1}}.
Now obviously this is easy enough to do if you don't care about efficiency, and my current implementation has been serving me well up till now. But now I'm having to deal with objects that have 6 levels and large arrays of data.
If anyone has a solution or link to one that would be awesome :)
Cheers
EDIT: Current implementation looks like this. It works (and deals with circular references). But is too slow.
/**
* Returns a sanitised string of an object, removing any functions and unwanted properties.
* #param {int} obj. The object to be stringified
* #param {Array[]} ignoreList. A array of object properties that should be removed.
*/
function sanitise(obj, ignoreList){
if(obj == undefined){
throw "Can't sanitise an undefined object"
}
var entry = JSON.parse(JSON.stringifyOnce(obj));
for(var i in entry){
if(entry.hasOwnProperty(i)){
if(contains(ignoreList, i)){
delete entry[i];
} else if(typeof(entry[i]) == "object" && entry[i] != null){
entry[i] = sanitise(entry[i], ignoreList);
}
}
}
return entry;
}
JSON.stringifyOnce = function(obj, replacer, indent){
var printedObjects = [];
var printedObjectKeys = [];
function printOnceReplacer(key, value){
var printedObjIndex = false;
printedObjects.forEach(function(obj, index){
if(obj===value){
printedObjIndex = index;
}
});
if ( key == ''){ //root element
printedObjects.push(obj);
printedObjectKeys.push("root");
return value;
}
else if(printedObjIndex+"" != "false" && typeof(value)=="object"){
if ( printedObjectKeys[printedObjIndex] == "root"){
return "(pointer to root)";
}else{
return "(see " + ((!!value && !!value.constructor) ? value.constructor.name.toLowerCase() : typeof(value)) + " with key " + printedObjectKeys[printedObjIndex] + ")";
}
}else{
var qualifiedKey = key || "(empty key)";
printedObjects.push(value);
printedObjectKeys.push(qualifiedKey);
if(replacer){
return replacer(key, value);
}else{
return value;
}
}
}
return JSON.stringify(obj, printOnceReplacer, indent);
};
Okay, figured out a pretty nice way. You just make an ignore list with roughly the same object structure as the object to be ignored.
function ignore(obj, list){
for(var i in list){
var type = Object.prototype.toString.call(list[i]);
if(type == "[object String]"){
delete obj[i];
}
else if (type == "[object Object]"){
ignore(obj[i], list[i])
}
else if (type == "[object Array]"){
var objList = obj[i];
var subList = list[i][0];
for(var n in objList){
ignore(objList[n], subList)
}
}
}
}
x = {a:1, b:[{c:1, d:1}, {c:1, d:1}, {c:1, d:1}], e:1}
ignoreList = {'e':'e', 'b':[{'c':'c'}]}
ignore(x, ignoreList) => {a:1, b:[{d:1}, {d:1}, {d:1}]}
We can create a look-up table object for the original object, to delete any given key in O(1) time. The implementation will involve you adding custom functions to add/remove from the object.
(function() {
var lookUpTable = {};
myObj.prototype.insert = function(key, value) {
// add key to the myObj
// insert an Entry for parent of key in lookUpTable
// lookUpTable = { "a" : [myObj.b, myObj, myObj.c.d.e] }
}
myObj.prototype.ignore = function(ignoreList) {
for( key in ignoreList ) {
for( parent in lookUpTable[key] )
delete parent[key];
delete lookUpTable [key];
}
}
}());
Now you can call the insert function to insert the key-value:
myObj.insert('a.b.c.d', ['p', 'g']);
and call the ignore function to delete the object:
myObj.ignore(['d', 'e']);
Sorry for just giving the incomplete code. But, you should be able to implement the details quiet easily. Hope you get the idea.
For the example given by you:
obj = {a:[{b:1, c:1}, {b:1, c:1}, {b:1, c:1}]
and you want to ignore all the 'b's. Note that the lookup table entry values were arrays and not just a single value. This is where the power of ignoring multiple entries with the same name, comes in. In this case, the entry for 'b' would be something like this.
lookupTable = {
b : [ // The parent objects of 'b'
obj['a'][0],
obj['a'][1],
obj['a'][2]
]
}
Basically, the lookuptable holds an array of references to all the objects that contain the key 'b'. So, you iterate through each of these parent objects and delete their 'b' entry.
$.each(lookupTable['b'], function( parent ) {
delete parent['b']; // Deletes 'b' inside of every parent object
});
You populate this lookup table entry while inserting into obj or while obj is loaded for the first time. If obj is hard-coded, you could also generate the lookupTable once and hard-code it. Probably in along with your minify Javascript scripts. Although populating it at run-time is also quiet fine.

Create object with key:value in one line

I need implement this in one line, if possible:
I have an object
var object1 = {};
object1['key_1'] = "value_1";
object1['key_2'] = "value_2";
object1['key_3'] = "value_3";
I need pass to an function one item from object (not only value ), key - only string value
for (var key in object1)
FunctionTemp({key:object1[key]}); // - this don't work as I need, and eval() method I don't want
maybe there is something like this
FunctionTemp((new {})[key]=object1[key]) - its don't work!!! :)
Since you really want it in one line you can do it like this:
var temp;
for (var key in object1)
FunctionTemp(((temp = {}) && (temp[key] = object1[key]))? temp: null);
but I think it is no longer readable as it is, the most ideal solution would be to break it down into several lines.
var temp;
for (var key in object1) {
temp = {};
temp[key] = object1[key];
FunctionTemp(temp);
}
What you're asking for is not possible without a function.
What you want to do is this:
var key = getKey(); //some means of determining a key dynamically
var val = getVal(); //some means of determining a value dynamically
var obj = {};
obj[key] = val;
this.doSomething(obj);
What you need is another method that assembles the object based on the dynamic key/value.
this.doSomething(_.object([[getKey(), getVal()]]));

Categories

Resources