[Angular] Creating an Observable Store with Rx
The API for the store is really simple:
/* set(name: string, state: any); select<T>(name: string): Observable<T> */
There are two methods, set() & select().
Store:
import {Observable} from 'rxjs/Observable'; import {BehaviorSubject} from 'rxjs/BehaviorSubject'; import {IState} from './state'; import 'rxjs/add/operator/pluck'; import 'rxjs/add/operator/distinctUntilChanged'; const state: IState = { playList: undefined }; export class Store { /*Because store usually has a default value, BehaviorSubject is suitable for that*/ private subject = new BehaviorSubject<IState>(state); /*Create a observable store*/ private store = this.subject .asObservable() // convert to an observable .distinctUntilChanged(); // performance improve /*Get value from subject*/ get value() { return this.subject.value; } set(name: string, state: any) { const nextState = { ...this.value, [name]: state }; this.subject.next(nextState); } select<T>(name: string): Observable<T> { // get prop value from observable return this.store.pluck(name); } }
interface:
export interface IState { playList: any[] }
Component:
import { Component } from '@angular/core'; import {Store} from './store'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { todos$ = this.store.select<any[]>('todos'); constructor(private store: Store) { this.store.set('todos', [ {id: 1, name: 'Learning Angular'}, {id: 2, name: 'Learning Redux'} ]); } }
<div> <ul *ngFor="let todo of todos$ | async"> <li>{{todo.name}}</li> </ul> </div>