Reputation: 5243
I have following code
var s = storage('foo');
s.bar = 100;
storage('foo', s);
storage
returns an object from some storage media. I then change the value of one property of the object and send it to storage
again. My question is is there any way to make it a one liner? Something like
storage('foo', storage('foo').bar = 100);
But the above code only saves 100
instead of entire foo
object.
Here is the storage
function, it stores on localstorage but makes it object storage instead of string storage:
function storage(item, value) {
if(value!=null) {
var result = (storage()) ? storage() : {};
if(item) result[item] = value;
return localStorage.setItem('storage', JSON.stringify(result))
} else return (item) ? storage()[item] : JSON.parse(localStorage.getItem('storage'));
}
Edit: So I ended up with following one line change in storage function. But this does not account for multidimensional usage. So I will welcome any suggestions.
function storage(item, value, property) {
...
if(item) (property) ? result[item][property] = value : result[item] = value;
...
}
Upvotes: 1
Views: 2488
Reputation: 816790
The reasonably thing to do, if you cannot change the storage
function, is to create another function:
function set_storage(obj, prop, val) {
var s = storage(obj);
obj[prop] = val;
storage(obj, s);
}
// usage
set_storage('foo', 'bar', 100);
If you can change storage though, this would be an even better way. jQuery.data
works similarly.
There are ways to do this in (almost) one line, with the help of the comma operator [MDN], but it ain't pretty:
var s = storage('foo');
storage('foo', (s.bar = 100, s));
Since you said storage
is your function, overloading it seems to be a good way. It would go like this:
function storage(key, prop, val) {
var storage = JSON.parse(localStorage.getItem('storage'));
if(arguments.length === 0) {
return storage;
}
else if (arguments.length === 1) {
// only one argument passed, return the value with key `key`
return storage[key];
}
else if (arguments.length === 2) {
// set `key` to `prop` (`prop` contains the actual value)
storage[key] = prop;
}
else {
// set property `prop` of object in `key` to value `val`
storage[key][prop] = val;
}
localStorage.setItem('storage', JSON.stringify(storage));
}
// Usage
// get `foo`:
var foo = storage('foo');
// set `foo`:
storage('foo', {bar: 42});
// set foo.bar
storage('foo', 'bar', 100);
I hope it gives you some idea.
Upvotes: 2
Reputation: 75629
You can make a function which accepts a function that changes the object:
function changeObject(key, func) {
var obj = storage(key);
func(obj);
storage(key, obj);
}
changeObject('foo', function (s) { s.bar = 100; });
Upvotes: 0
Reputation: 75327
As storage
returns an object
, theres a (very) good chance you can do*;
storage('foo').bar = 100;
console.log(storage('foo').bar); // should give 100.
... directly, as objects are "pass by reference"-esque.
* A situation where this would not be the case would be where storage
returns a copy of the object stored, rather than the object itself; therefore any updates you make to the returned object will not have an affect on the object in storage.
Upvotes: 0