Save Javascript objects in sessionStorage
Asked Answered
P

10

195

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.

Prohibitive answered 31/5, 2011 at 21:8 Comment(5)
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.Ignition
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.Irregularity
"Can I avoid this limitation?" seems like a questionWorkout
Well limitation or not, this question helped me solve a problem, so thanks.Octangular
Just wondering if a decade later you still stand by your accepted answer? The top voted answer is 5 times more popular.Chase
M
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.

Monandry answered 31/5, 2011 at 21:28 Comment(2)
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?Prohibitive
If JSON isn't enough, you could always write your own object serialization methods.Monandry
D
154

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);
Dupe answered 2/10, 2015 at 11:5 Comment(0)
S
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/

Squatness answered 25/4, 2012 at 22:40 Comment(5)
This works for me. I get a working Json object after calling $.parseJSON()Phosphaturia
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.Thromboembolism
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.Hautegaronne
Just tried your fiddle and I get undefined undefined is undefined years old.Quadrilateral
@Hautegaronne 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))Peculiarize
M
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.

Monandry answered 31/5, 2011 at 21:28 Comment(2)
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?Prohibitive
If JSON isn't enough, you could always write your own object serialization methods.Monandry
E
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');
Easy answered 15/3, 2017 at 2:38 Comment(0)
E
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))
    };
Easy answered 26/11, 2014 at 6:55 Comment(2)
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.Danner
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 */ }Inessa
P
4
    var user = {'name':'John'};
    sessionStorage['user'] = JSON.stringify(user);
    console.log(sessionStorage['user']);
Phelan answered 19/1, 2016 at 7:46 Comment(0)
G
4

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

Gi answered 23/5, 2018 at 19:20 Comment(0)
C
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);
Coontie answered 27/3, 2020 at 20:5 Comment(0)
Q
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)
})
Quadrifid answered 11/10, 2017 at 11:58 Comment(0)
B
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
       };
    
Blow answered 23/5, 2022 at 15:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.