Storage event not firing

Viewed 30558

Attaching the event:

$(window).on("storage", function (e) {
   //callback not getting hit
});

Trying to fire the event:

localStorage.setItem("test", "123");

I have two tabs open, both listening to the storage event. I can see the localStorage getting updated correctly on both tabs. However when I change localStorage on one tab, the other never fires the event. Any ideas?

Tried on Chrome/Firefox. Domain format is https://www.xxx.yyy.zzz.

7 Answers

StorageEvent is fired in different page with the same domain.

From MDN

The StorageEvent is fired whenever a change is made to the Storage object.

This 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。

As others in the answers noted, the storage event only get picked up (by the listener) if the localStorage was changed in another browser's tab/window (of the same app), but not within the context of the current tab.

Detect storage changes in the current tab:

window.addEventListener('storage', console.log)

window.localStorage.setItem('test', '123')
window.dispatchEvent( new Event('storage') ) // <----- 

A manual storage event is dispatched.

This will effectively trigger the storage event listener twice on other tabs/windows (of the same app), but in certain situations this shouldn't be a problem.

If even testing between different tabs/pages and still not seeing the event... I've found that the event will only fire if the key already exists.

It seems it's more like an onchange event.

Set a default value to the localStorage key, if even undefined and then test.

I'd call this a Chrome bug, as Firefox and Safari are firing correctly, but it is what it is.

An additional point to vsync's answer above is you can fire StorageEvent instead of Event and pass in an object so the fired event will match the browser default.

const oldValue = window.localStorage.getItem('test');
window.localStorage.setItem('test', newValue);
const event = new StorageEvent('storage', {
  key: 'test',
  oldValue,
  newValue,
  ...
});

window.dispatchEvent(event);

You could always use a utility like localDataStorage to fire the events for you, in the same window/tab, whenever a key value changes, such as those made by the set or remove methods. You can also use it to transparently set/get any of the following "types": Array, Boolean, Date, Float, Integer, Null, Object or String.

[DISCLAIMER] I am the author of the utility [/DISCLAIMER]

Once you instantiate the utility, the following snippet will allow you to monitor the events:

function localStorageChangeEvents( e ) {
    console.log(
        "timestamp: "     + e.detail.timestamp + " (" + new Date( e.detail.timestamp ) + ")" + "\n" +
        "key: "           + e.detail.key     + "\n" +
        "old value: "     + e.detail.oldval  + "\n" +
        "new value: "     + e.detail.newval  + "\n"
    );
};
document.addEventListener(
    "localDataStorage"
    , localStorageChangeEvents
    , false
);
Related