views:

216

answers:

4

I want to make a function that add an item to my localStorage object. E.g.:

alert(localStorage.getItem('names').addItem('Bill').getItem('names'));

The first method is getItem which gets the item for localStorage objects... but addItem would be a custom function. This chain of functions would finally alert Bill.

So, how would I make this function chain to localStorage?

+5  A: 

This is impossible.

If getItem('names') returns Bill, you can't call addItem on it.
It would be possible to add addItem and getItem methods to every item in the storage, but it would be a horrible idea.

SLaks
jQuery overload.
Jani Hartikainen
**it is possible** (without augmenting localStorage). see my answer. Not a very useful case, but a good demonstration of the **decorator pattern**.
galambalazs
@galambalazs: It's not possible using his exact calls.
SLaks
getItem() breaks the chain, that's obvious, but you don't need to add methods to every element in the storage.
galambalazs
@Jani there is no jQuery here...
Oscar Godson
No, there isn't, but what you were trying to do was very jQuery-like in a bad way :D
Jani Hartikainen
How would suggest making an addItem function? if not adding an item is a lot of extra markup. I'd prefer doing it in a DRY way...
Oscar Godson
+5  A: 

This is possible if you create a wrapper/decorator object that makes chaining possible. This is how jQuery works for example. But it is useless in this case.

I made a possible implementation, though.

But getItem will break the chain (so it should always be used at the end).

storage().setItem('names', 'Bill').getItem('names'); // or
storage().setItem('names').addItem('Bill').getItem('names'); // or
storage().key('names').value('Bill').set().get('names');

Implementation

(function( window, undefined ) {

var storage = function( key, value ) {
  return new storage.init( key, value );
};

storage.init = function( key, value ) {
  this._key   = key;
  this._value = value;
};

storage.init.prototype = {

  key: function( key ) {
    this._key = key;
    return this;
  },

  value: function( value ) {
    this._value = value;
    return this;
  },

  get: function( key ) {
    key = isset(key) || this._key;
    return localStorage.getItem( key );
  },

  set: function( key, value ) {
    this._key   = key   = isset(key)   || this._key;
    this._value = value = isset(value) || this._value;
    if ( key && value ) {
      localStorage.setItem( key, value );
    }
    return this;
  },

  addItem: function( value ) {
    this._value = isset(value) || this._value;
    if ( this._key && value !== undefined ) {
      localStorage.setItem( this._key, value );
    }
    return this;
  },

  // aliases...
  getItem: function( key ) {
    return this.get( key );
  },
  setItem: function( key, value  ) {
    return this.set( key, value );
  }
};

function isset( value ) {
  return value !== undefined ? value : false;
}

window.storage = storage;

})( window );
galambalazs
Thank you very much, i must be screwing something up tho. I copy right below it and im getting a storage.setItem is not a function?
Oscar Godson
@Oscar – You forgot the parentheses: `alert(storage().setItem('names').addItem('Bill').getItem('names'))`
Marcel Korpel
@Oscar Marcel is right, it now creates instances for storage chains, so you need to write `storage()`. I can modify it to be only one object, but it may become less robust.
galambalazs
Awh, i see, yeah so: alert(storage().setItem('names').addItem('Bill').addItem('Tom').getItem('names')); alerts Tom and so does localStorage.getItem('names'). Almost perfect, but how can i return Bill, Tom, etc in that same alert? Basically, return them in an array? Sorry if this stuff is way over my head. Im trying to learn though... I like this style more than just plain functions...
Oscar Godson
A: 

The simplest thing would be to not do this at all :)

If that doesn't work, then there are solutions like modifying the native getItem function but that's a really bad idea. The best way would be to write a wrapper around localStorage, much like what jQuery does to DOM nodes, and use that wrapper to get and put items in local storage. The wrapper could have an interface like:

ApplicationStorage
    getItem()
    setItem()
    key()
    removeItem()

Then define acceptable type wrappers like Array within ApplicationStorage that have methods like addItem

ApplicationStorage.Array
    addItem()

When applicationStorage.getItem("names") is called, return an object of ApplicationStorage.Array that contains the method addItem which will make chaining possible.

Anurag
A: 

getItem('names').addItem('Bill').getItem('names')

I am confused, how do you get an item that has not been added???

getItem returns an object contains addItem method, and addItem method returns an object cotains getItem method

anyway, have a look this tutorial, not completely solving your problem, but will give you an idea. http://guanfenglin.spaces.live.com/blog/cns!4E0822BF6C959B7F!668.entry

James Lin