-
-
Save ccarrasc/fbf71c662a32775f9b93d85481b8d59d to your computer and use it in GitHub Desktop.
import { Injectable } from '@angular/core'; | |
import StorageService from './storage.service'; | |
@Injectable() | |
export class LocalStorageService extends StorageService { | |
private _storage = localStorage; | |
constructor() { | |
super(); | |
} | |
protected get storage(): Storage { | |
return this._storage; | |
} | |
} |
import { Injectable } from '@angular/core'; | |
import StorageService from './storage.service'; | |
@Injectable() | |
export class SessionStorageService extends StorageService { | |
private _storage = sessionStorage; | |
constructor() { | |
super(); | |
} | |
protected get storage(): Storage { | |
return this._storage; | |
} | |
} |
import { Observable, BehaviorSubject } from 'rxjs/Rx'; | |
abstract class StorageService { | |
private itemSources: Map<string, BehaviorSubject<string>> = new Map(); | |
protected abstract get storage(): Storage; | |
constructor() { | |
addEventListener('storage', (event: StorageEvent) => { | |
if (event.key) { | |
if (this.itemSources.has(event.key)) { | |
this.itemSources.get(event.key).next(event.newValue); | |
} | |
} | |
}); | |
} | |
getItem(key: string): Observable<string> { | |
if (!this.itemSources.has(key)) { | |
this.itemSources.set(key, new BehaviorSubject<string>(this.storage.getItem(key))); | |
} | |
return this.itemSources.get(key).asObservable(); | |
} | |
setItem(key: string, value: string) { | |
try { | |
this.storage.setItem(key, value); | |
if(this.itemSources.has(key)) { | |
this.itemSources.get(key).next(this.storage.getItem(key)); | |
} | |
} | |
catch (error) { | |
this.itemSources.get(key).error(error); | |
} | |
} | |
removeItem(key: string) { | |
this.storage.removeItem(key); | |
if (this.itemSources.has(key)) { | |
this.itemSources.get(key).next(this.storage.getItem(key)); // Expect to be null | |
this.itemSources.delete(key); | |
} | |
} | |
clear() { | |
this.storage.clear(); | |
this.itemSources.forEach((itemSource: BehaviorSubject<string>) => { | |
itemSource.next(null); | |
itemSource.complete(); | |
}); | |
this.itemSources.clear(); | |
} | |
} | |
export default StorageService; |
In your eventListener 'storage', shouldn't you also check this ? :
event.storageArea === this.storage
In your eventListener 'storage', shouldn't you also check this ? :
event.storageArea === this.storage
I don't think so since the event is typed to StorageEvent
: https://developer.mozilla.org/en-US/docs/Web/API/StorageEvent
Your StorageEvent can be fired from local and session from my understanding ? Am I wrong ?
If yes, if you have the same key from your local and session storage, you might override the wrong storage in addition of the good one.
@VincentQueignec I don't think so, but I do not have any unit tests to validate that and this is also a very old snippet.
From what I see, StorageService
is abstract, and the concrete implementations specify the storage type. I don't see how you can cross into the wrong storage when using a concrete type (see the getter for storage
).
Good work!