6

I am displaying notifications to users using pnotify plugin. However I want to remove notification on all tabs if user closes notification in 1 tab by clicking X icon.

I use localstorage for this, each time a new notification is shown to the user, it gets added to the localStorage. When user presses X icon, I do localStorage.removeItem(key). How do I listen to this event to close the notification in all tabs?

My listener is below:

$(window).bind('storage', function(e) {
    // if it was removed
    if (e.originalEvent.newValue == null) {
        var notificationObject = e.originalEvent.oldValue;

        // call remove function on pnotify object
        notificationObject.remove();
    }
});

I noticed that newValue turns into null if it was removed, in theory this would work (have not tested yet), but is it reliable in terms of will it always return null if removeItem was called on that item? What if the item value changes to null, it will then trigger that event since the value changed right?

GGio
  • 7,563
  • 11
  • 44
  • 81
  • if (e.originalEvent.newValue == null) should be if (!e.originalEvent.newValue) – ymz Jan 19 '16 at 22:26
  • 1
    @ymz there's no need to handle `undefined` here, the spec dictates that `null` is returned when the key is not present. – user247702 Jan 19 '16 at 22:35

2 Answers2

5

Local Storage stores everything as a string.

localStorage.setItem("foo", null);

// returns "null"
localStorage.getItem("foo");

And indeed, newValue is null when it's removed. MDN: StorageEvent says:

The new value of the key. The newValue is null when the change has been invoked by storage clear() method or the key has been removed from the storage. Read only.

Therefore, it is safe to check for null by using === null.

user247702
  • 23,641
  • 15
  • 110
  • 157
2
$(window).on("itemRemoved", function(e, args) {
  console.log(e, args);
  if (!localStorage.getItem(args)) {
    // do stuff
  }
})

fn = localStorage.removeItem; 
localStorage.removeItem = function() { 
  var args = arguments; 
  setTimeout(function() {
    $(window).trigger("itemRemoved", [args[0]])
  }); 
 return fn.call(localStorage, args[0]); 
}
guest271314
  • 1
  • 15
  • 104
  • 177
  • This looks like what I need. I guess localStorage does not have this built in and allow us to extend it by overriding the removeItem function. Did not know that was possible. Thanks, I will give this a try. – GGio Jan 19 '16 at 22:46