Created
June 11, 2016 17:10
-
-
Save deebloo/a5266b2e71d833524c3655bad3ae486c to your computer and use it in GitHub Desktop.
Typescript and RXJS application state with history
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { Injectable } from '@angular/core'; | |
| import { Subject } from 'rxjs/Subject'; | |
| @Injectable() | |
| export class AppStateService { | |
| changes: Subject<any> = new Subject(); | |
| private state: any = {}; | |
| private history: any[] = []; | |
| private historyPos: number = 0; | |
| private historyLength: number = 20 | |
| // set the new application state | |
| setState(key, state) { | |
| this.updateState(key, state); | |
| if(this.historyPos < this.history.length) { | |
| this.history.length = this.historyPos + 1; | |
| } | |
| this.history.push({ key, state }); | |
| this.historyPos = (this.history.length - 1); | |
| if(this.history.length > this.historyLength) { | |
| this.history.shift(); | |
| } | |
| } | |
| // return the current state | |
| getState(key?) { | |
| const state = this.copy(this.state); | |
| if (key) { | |
| return state[key]; | |
| } else { | |
| return state; | |
| } | |
| } | |
| // replay enture history | |
| replay() { | |
| this.history.forEach(past => this.updateState(past.key, past.state)); | |
| } | |
| // replay events from current position in history | |
| catchUp() { | |
| let history = this.history.slice(this.historyPos, this.history.length); | |
| history.forEach(past => this.updateState(past.key, past.state)); | |
| } | |
| // go back in the states history | |
| goBack() { | |
| this.historyPos -= 1; | |
| let past = this.history[this.historyPos]; | |
| if(past) { | |
| this.updateState(past.key, past.state); | |
| } | |
| } | |
| // update the app state | |
| private updateState(key, state) { | |
| this.state[key] = this.copy(state); | |
| this.changes.next(this.state); | |
| } | |
| // create a new instance of the state | |
| private copy(state): any { | |
| if (!state) return; | |
| try { | |
| return JSON.parse(JSON.stringify(state)); | |
| } catch(e) { | |
| console.error('your state must be valid json'); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment