observe localstorage changes in js
Solution 1
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.
Solution 2
The localDataStorage interface (a handy wrapper for the HTML5 localStorage API) conveniently fires change events on the same page/tab/window in which the storage event occurred. Disclaimer: I am the author of the interface.
Once you install localDataStorage, this sample code will let you see those change events:
function nowICanSeeLocalStorageChangeEvents( e ) {
console.log(
"subscriber: " + e.currentTarget.nodeName + "\n" +
"timestamp: " + e.detail.timestamp + " (" + new Date( e.detail.timestamp ) + ")" + "\n" +
"prefix: " + e.detail.prefix + "\n" +
"message: " + e.detail.message + "\n" +
"method: " + e.detail.method + "\n" +
"key: " + e.detail.key + "\n" +
"old value: " + e.detail.oldval + "\n" +
"new value: " + e.detail.newval + "\n" +
"old data type: " + e.detail.oldtype + "\n" +
"new data type: " + e.detail.newtype
);
};
document.addEventListener(
"localDataStorage"
, nowICanSeeLocalStorageChangeEvents
, false
);
Solution 3
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);
}
Solution 4
window.addEventListener('storage', ...)
works
Make sure you are using the correct event properties.
Admin
Updated on November 04, 2021Comments
-
Admin over 2 years
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. -
Iamnino over 2 yearsthis is not what the OP is asking for. as it was already pointed out an event listener for "storage" does NOT work on the same page, the changes are done. please read the note in the MDN docs: developer.mozilla.org/en-US/docs/Web/API/Window/storage_event