Skip to content

Instantly share code, notes, and snippets.

@pankajparkar
Last active May 9, 2022 05:30
Show Gist options
  • Save pankajparkar/9614ffaea22aeaf664e35d725512a222 to your computer and use it in GitHub Desktop.
Save pankajparkar/9614ffaea22aeaf664e35d725512a222 to your computer and use it in GitHub Desktop.
Storage Service implementation and consumptions
import { Injectable } from '@angular/core';
import { Entity } from '../enums';
import { FleetPosition, Player } from '../models';
import { StorageService } from './storage.service';
@Injectable({
providedIn: 'root'
})
export class ApiService {
constructor(
private storage: StorageService,
) { }
getPlayers() {
return this.storage.get<Player[]>(Entity.PLAYERS);
}
updatePlayer(player: Player): void {
const players = this.getPlayers();
const playerIndex = players.findIndex((p: Player) => p.id === player.id);
// Update player
if (playerIndex > -1) {
players[playerIndex] = player;
}
// Add player
else {
players[players.length] = player;
}
this.storage.set(Entity.PLAYERS, players);
}
updatePlayers(players: Player[]) {
this.storage.set(Entity.PLAYERS, players);
}
clearPlayer() {
this.storage.set(Entity.PLAYERS, "[]");
}
getPositions(playerId: string) {
const players = this.getPlayers();
const player = players.find(p => p.id === playerId)
return player?.positions || [];
}
updatePositions(playerId: string, positions: FleetPosition) {
const players = this.getPlayers();
const player = players.find(p => p.id === playerId);
if (player) {
player.positions = positions;
this.storage.set(Entity.PLAYERS, players);
}
}
clearPositions(playerId: string) {
const players = this.getPlayers();
const player = players.find(p => p.id === playerId);
if (player) {
player.positions = {
horizontal: [],
vertical: [],
};
this.storage.set(Entity.PLAYERS, players);
}
}
}
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class StorageService {
constructor() { }
private getJSON(key: string) {
return JSON.parse(localStorage.getItem(key) ?? '{}');
}
get<T>(key: string) {
const result: unknown = localStorage.getItem(key);
try {
return JSON.parse(result as string) as T;
} catch (error) {
return result as T;
}
}
set(key: string, value: unknown) {
let valueToBeStored = value;
try {
valueToBeStored = JSON.stringify(value);
} finally {
localStorage.setItem(key, valueToBeStored as string);
}
}
getByProperty<T>(key: string, prop: string) {
const result = this.getJSON(key);
return result[prop] as T;
}
setByProperty(key: string, prop: string, propValue: unknown) {
const result = this.getJSON(key);
result[prop] = propValue ?? '';
this.set(key, result);
}
remove(key: string) {
try {
localStorage.removeItem(key);
} catch (error) {
console.error('Error removing data.');
}
}
removeProperty(key: string, prop: string) {
const result = this.getJSON(key);
delete result[prop];
this.set(key, result);
}
}
@AvinashDalvi89
Copy link

Nice idea. Version looks good. Major help is getProperty, setProperty and removeProperty.

@pankajparkar
Copy link
Author

Nice idea. Version looks good. Major help is getProperty, setProperty and removeProperty.

Yes, you pointed it out well. Indeed that was my initial thought about writing wrapper, and then the partial typings support.

@phalgunv
Copy link

phalgunv commented May 9, 2022

As JSON.stringify() could throw exceptions for "cyclic object value" and "BigInt". If it fails for "cyclic object value", trying to store the object in the local storage from the finally block will result in Object.toString(), [Object Object] to be stored in the localstorage. While reading back using JSON.parse() it would not be very useful.

You can consider using the replacer parameter of JSON.stringify() function to handle exceptions and move the code from finally to catch block.
cyclic object value:
https://stackoverflow.com/a/9382383/3423750
BigInt:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#usage_recommendations

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment