Storage event listener doesn't execute on current window

Viewed 1048

I have an angular 8+ application, and i am trying to work with localstorage and sessionstorage. Listening to sessionstorage or localstorage changes. Since its angular i am using the Event Manager class :

constructor( private elementRef: ElementRef, private eventManager: EventManager) {
    this.eventManager.addGlobalEventListener('window', 'storage', () => {
      console.log('Event listener.....');
    });
}

When i session storage set item, the above function does not execute. it is only executed when i go to the DevTools -> Application -> Storage then remove the item. I have read somewhere that the reason it is not executing is because it cant execute on the current browser tab/current window. Is the a way to make the event listener execute on current window or browser tab When the button is clicked ? i am using Chrome browser.

1 Answers

I can think of solution like create a service wrapper over localStorage object and use the EventManager to track the localStorage changes on other tab

local-storage.service

@Injectable({
  providedIn: "root"
})
export class LocalStorageService {
  private change = new EventEmitter();

  constructor(private eventManager: EventManager) {
    this.eventManager.addGlobalEventListener(
      "window",
      "storage",
      ({ key, oldValue, newValue }) => {
        if (key) { // this mean new item has been set
          this.change.emit({
            type: localStorageAction.set,
            key,
            oldValue,
            newValue
          });
        } else { // if key is null this mean the localstorage is cleared 
          this.change.emit({
            type: localStorageAction.clear
          });
        }
      }
    );
  }

  subscribe(handler) {
    return this.change.subscribe(handler);
  }

  clear() {
    localStorage.clear();

    this.change.emit({
      type: localStorageAction.clear
    });
  }

  getItem(key: string) {
    return localStorage.getItem(key);
  }

  key(index: number) {
    return localStorage.key(index);
  }
  get length() {
    return localStorage.length;
  }

  removeItem(key: string) {
    localStorage.removeItem(key);

    this.change.emit({
      type: localStorageAction.remove,
      key
    });
  }

  setItem(key: string, value) {
    const oldValue = localStorage.getItem("key");
    localStorage.setItem(key, value);

    this.change.emit({
      type: localStorageAction.set,
      key,
      oldValue,
      newValue: value
    });
  }
}

now by this service you can track changes like set,remove item,clear

demo

  • in the demo stackblitz keep change the localStorage that why you get notify about that changes.
  • you need to use this service instead of the localStorage object so you can get notify of the changes in the same window.
  • subscribe method return a subscription object.
Related