I was trying to figure out how to get a menu to appear and disappear based on being logged in in a previous post. But I think a better and possibly easier question would be, how can I watch for changes to localstorage?
I am using json web tokens in local storage for my authentication, I would love to watch for a change to localStorage and then re-update my view on new information.
I set my localStorage with this
localStorage.setItem('jwt', my_token);
The things I would like to do is check if I have a token, if I don't nothing happens, but when there is a change fire an event. I would especially like it if I could only watch for a certain named event like localStorage.getItem('jwt').
Thanks!
EDIT:
Gunter pointed me in the right direction but just in case anyone is still fairly confused by that, here is a plunker showing you how to do it. http://plnkr.co/edit/TiUasGdutCsll1nI6USC?p=preview
The key thing is to use window.addEventListener("storage",
. While the library probably does it the "right" way for angular, here is a "light" version I put together, using .bind(this) instead of mucking about in angular's internals.
import { Injectable, OnDestroy } from '@angular/core';
import { Subject } from 'rxjs/Subject';
import { share } from 'rxjs/operators';
@Injectable()
export class StorageService implements OnDestroy {
private onSubject = new Subject<{ key: string, value: any }>();
public changes = this.onSubject.asObservable().pipe(share());
constructor() {
this.start();
}
ngOnDestroy() {
this.stop();
}
public getStorage() {
let s = [];
for (let i = 0; i < localStorage.length; i++) {
s.push({
key: localStorage.key(i),
value: JSON.parse(localStorage.getItem(localStorage.key(i)))
});
}
return s;
}
public store(key: string, data: any): void {
localStorage.setItem(key, JSON.stringify(data));
this.onSubject.next({ key: key, value: data})
}
public clear(key) {
localStorage.removeItem(key);
this.onSubject.next({ key: key, value: null });
}
private start(): void {
window.addEventListener("storage", this.storageEventListener.bind(this));
}
private storageEventListener(event: StorageEvent) {
if (event.storageArea == localStorage) {
let v;
try { v = JSON.parse(event.newValue); }
catch (e) { v = event.newValue; }
this.onSubject.next({ key: event.key, value: v });
}
}
private stop(): void {
window.removeEventListener("storage", this.storageEventListener.bind(this));
this.onSubject.complete();
}
}