Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

observe localstorage changes in js

I have a single-page app in which I need to react on every change in localstorage, it looks something like:

    MyComponent {
    
    someFuncWhichIsCalledEveryTimeWhenLocalStorageChanges() {
        console.log('local storage changed!);
    }
    
    funcThatChangesLocalStorage() {
        localstorage.setItem('key',val);
        localstorage.getItem('key')
    }
    
    }

And I've tried to use localstorage event:

window.addEventListener('storage', function(event){
       ...
});

but that didn't work... so I'm thinking about using Observable<>, just don't know how to implement it properly.

like image 916
Tasha Herber Avatar asked Jun 08 '18 19:06

Tasha Herber


2 Answers

Huge caveat from the MDN docs: Window storage event:

[window.addEventListener('storage', ...)] won't work on the same page that is making the changes — it is really a way for other pages on the domain using the storage to sync any changes that are made.

So that's probably why it didn't work for you (and for me as well) - you were trying to respond to this listener on other parts of the same page.

like image 126
Yangshun Tay Avatar answered Sep 23 '22 13:09

Yangshun Tay


You can use a function that makes proxy methods on an object

function watchAnyObject(
  object = {},
  methods = [],
  callbackBefore = function () {},
  callbackAfter = function () {},
) {
  for (let method of methods) {
    const original = object[method].bind(object);
    const newMethod = function (...args) {
      callbackBefore(method, ...args);
      const result = original.apply(null, args);
      callbackAfter(method, ...args);
      return result;
    };
    object[method] = newMethod.bind(object);
  }
}

and use it like this

watchAnyObject(
  window.localStorage,
  ['setItem', 'getItem', 'removeItem'],
  (method, key, ...args) =>
    console.log(`call ${method} with key ${key} and args ${args}`),
);

you can add your listener someFuncWhichIsCalledEveryTimeWhenLocalStorageChanges in the component constructor

constructor() {
  watchAnyObject(window.localStorage, ['setItem', 'getItem', 'removeItem'], this.someFuncWhichIsCalledEveryTimeWhenLocalStorageChanges);
}
like image 34
Dmitry Kovganov Avatar answered Sep 25 '22 13:09

Dmitry Kovganov