198

SessionStorage and LocalStorage allows to save key/value pairs in a web browser. The value must be a string, and save js objects is not trivial.

var user = {'name':'John'};
sessionStorage.setItem('user', user);
var obj = sessionStorage.user; // obj='[object Object]' Not an object

Nowadays, you can avoid this limitation by serializing objects to JSON, and then deserializing them to recover the objects. But the Storage API always pass through the setItem and getItem methods.

sessionStorage.setItem('user', JSON.stringify(user));
var obj = JSON.parse(sessionStorage.getItem('user')); // An object :D

Can I avoid this limitation?

I just want to execute something like this:

sessionStorage.user.name; // 'John'
sessionStorage.user.name = 'Mary';
sessionStorage.user.name // 'Mary'

I have tried the defineGetter and defineSetter methods to intercept the calls but its a tedious job, because I have to define all properties and my target is not to know the future properties.

5
  • 1
    I've thought of that myself. I suppose a lot of people have. But I don't think getter and setter methods are too much of a burden. BTW; you can serialize and parse with JavaScript and MS is finally supporting the same standard objects as everyone else. The days of need for packages like JSON and jQuery are coming rapidly to an end. Commented Mar 18, 2013 at 7:45
  • 1
    I guess I don't see the limitation. It may seem like overkill to use JSON.stringify and JSON.parse if you only ever have trivial objects, but if you have even good-sized data objects those two methods are doing a lot of work for you. Commented Aug 5, 2013 at 15:26
  • 5
    "Can I avoid this limitation?" seems like a question Commented Jun 19, 2014 at 21:17
  • 1
    Well limitation or not, this question helped me solve a problem, so thanks. Commented Jun 28, 2016 at 19:32
  • Just wondering if a decade later you still stand by your accepted answer? The top voted answer is 5 times more popular. Commented Mar 30, 2022 at 1:26

10 Answers 10

159

The solution is to stringify the object before calling setItem on the sessionStorage.

var user = {'name':'John'};
sessionStorage.setItem('user', JSON.stringify(user));
var obj = JSON.parse(sessionStorage.user);
Sign up to request clarification or add additional context in comments.

Comments

118

Could you not 'stringify' your object...then use sessionStorage.setItem() to store that string representation of your object...then when you need it sessionStorage.getItem() and then use $.parseJSON() to get it back out?

Working example http://jsfiddle.net/pKXMa/

5 Comments

This works for me. I get a working Json object after calling $.parseJSON()
Some systems like Web Api authentication return objects in the form of Object { propertyOneWithoutQuotes : "<value1>", ... propertyNWithoutQuotes : "<valueN>" } which need to go through "stringify". If there are multiple sources it might be better to use stringify to standardize the data.
This is very good answer. It is good to use JSON.stringify() to serialize object and store in sessionStorage. Then, it use $.parseJSON() to de-serialize the string to get the object.
Just tried your fiddle and I get undefined undefined is undefined years old.
@Thomas.Benz You are a Genius !!! Thank you so much. Your simple answer helped me solve an important problem in our code. ("It is good to use JSON.stringify() to serialize object and store in sessionStorage. Then, it use $.parseJSON() to de-serialize the string to get the object."(SIC))
23

Either you can use the accessors provided by the Web Storage API or you could write a wrapper/adapter. From your stated issue with defineGetter/defineSetter is sounds like writing a wrapper/adapter is too much work for you.

I honestly don't know what to tell you. Maybe you could reevaluate your opinion of what is a "ridiculous limitation". The Web Storage API is just what it's supposed to be, a key/value store.

2 Comments

Sorry if I have used an inappropriate word with 'ridiculous'. Replace it with 'could be so interesting'. I think that the webStorage is one of the most exciting improvement of the new web. But save only strings in the value key-map I think is a limitation. It seems like a cookies' sequel. I know that the Storage is a specification non only for Javascript language, but serialize objects could be an interesting improvement. What do you think?
If JSON isn't enough, you could always write your own object serialization methods.
19

This is a dynamic solution which works with all value types including objects :

class Session extends Map {
  set(id, value) {
    if (typeof value === 'object') value = JSON.stringify(value);
    sessionStorage.setItem(id, value);
  }

  get(id) {
    const value = sessionStorage.getItem(id);
    try {
      return JSON.parse(value);
    } catch (e) {
      return value;
    }
  }
}

Then :

const session = new Session();

session.set('name', {first: 'Ahmed', last : 'Toumi'});
session.get('name');

Comments

6

Use case:

 sesssionStorage.setObj(1,{date:Date.now(),action:'save firstObject'});
 sesssionStorage.setObj(2,{date:Date.now(),action:'save 2nd object'}); 
 //Query first object
  sesssionStorage.getObj(1)
  //Retrieve date created of 2nd object
  new Date(sesssionStorage.getObj(1).date)

API

Storage.prototype.setObj = function(key, obj) {

        return this.setItem(key, JSON.stringify(obj))
    };
    
    Storage.prototype.getObj = function(key) {
        return JSON.parse(this.getItem(key))
    };

2 Comments

I thought one of the best practices in javascript was to not prototype objects that you do not own. Using Storage.prototype.setObj seems like a bad idea.
just adding the obligatory.. make sure you don't add this prototype code - and rely on it exclusively - without first checking if the browser supports it Storage: if (typeof (Storage) !== "undefined"){ /* browser supports it */ }
4
    var user = {'name':'John'};
    sessionStorage['user'] = JSON.stringify(user);
    console.log(sessionStorage['user']);

Comments

4

Session storage cannot support an arbitrary object because it may contain function literals (read closures) which cannot be reconstructed after a page reload.

Comments

4

You can create 2 wrapper methods for saving and retrieving object from session storage.

function saveSession(obj) {
  sessionStorage.setItem("myObj", JSON.stringify(obj));
  return true;
}

function getSession() {
  var obj = {};
  if (typeof sessionStorage.myObj !== "undefined") {
    obj = JSON.parse(sessionStorage.myObj);
  }
  return obj;
}

Use it like this:- Get object, modify some data, and save back.

var obj = getSession();

obj.newProperty = "Prod"

saveSession(obj);

Comments

3

You could also use the store library which performs it for you with crossbrowser ability.

example :

// Store current user
store.set('user', { name:'Marcus' })

// Get current user
store.get('user')

// Remove current user
store.remove('user')

// Clear all keys
store.clearAll()

// Loop over all stored values
store.each(function(value, key) {
    console.log(key, '==', value)
})

Comments

1

CustomHook is one of the best ways to store a token as an object by using sessionStorage in React 17.0.1.

Follow these instructions:

  1. Implement sessionStorage get/set inside a custom function:

    export default function useToken() {
       const getToken = () => {
         const tokenString = sessionStorage.getItem('token');
         const userToken = JSON.parse(tokenString);
         return userToken?.token;
       };
    
       const [token, setToken] = useState(getToken());
    
       const saveToken = (userToken) => {
         sessionStorage.setItem('token', JSON.stringify(userToken));
         setToken(userToken.token);
       };
    
    
       return {
         setToken: saveToken,
         token,
       };
     }
    
  2. This function can be imported and used as a hook in other components like:

     import useToken from './useToken';
    
     const { token, setToken} = useToken(); // call CustomHook
    
     const handleSubmit = async (event) => {
         event.preventDefault();
         // call functionAPI
         const token = await loginUser({
           username,
           password,
         });
         setToken(token); // AUTOMATICALLY token will be stored to sessionStorage of browser
       };
    

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.