@ridder/state
    TypeScript icon, indicating that this package has built-in type declarations

    1.0.4 • Public • Published

    State model

    1. Description
    2. Installation
    3. Usage
    4. Methods
    5. Git repository
    6. Run tests
    7. Build
    8. Publish to npm
    9. Version

    1. Description

    StateModel and StateComponent are a couple of parent classes used for custom state models services in Angular applications based on RxJs library.

    2. Installation

    Install the module into your application and save it as a dev dependency in your package.json file

    npm install ridder/state --save-dev
    

    3. Usage

    In order to use the StateModel you have to to create a custom service model in your application and extend StateModel<T>:

    import { Injectable } from '@angular/core';
    import { ReplaySubject } from 'rxjs';
    import { StateModel } from '@ridder/state';
     
    export interface CounterState {
      value: number;
    }
     
    @Injectable({
      providedIn: 'root'
    })
    export class CounterService extends StateModel<CounterState> {
     
      constructor() {
        super();
     
        // set initial value of the state if it's required
        this.resetState();
      }
     
      private initState: CounterState = {
        value: 0
      };
     
      private state: CounterState = {...this.initState};
     
      public getState(): ReplaySubject<CounterState> {
        return this.get();
      }
     
      public setState(properties: CounterState): void {
        this.state = {...this.state, ...properties};
        this.set(this.state);
      }
     
      public resetState(): void {
        this.setState({...this.initState});
      }
     
      public increment(): void {
        const newValue = this.state.value + 1;
        this.setState({...this.state, value: newValue});
      }
     
      public decrement(): void {
        const newValue = this.state.value - 1;
        this.setState({...this.state, value: newValue});
      }
    }

    Register this model service into a parent store service:

    import { Injectable } from '@angular/core';
    import { CounterService } from './counter.service';
     
    @Injectable({
      providedIn: 'root'
    })
    export class StoreService {
     
      constructor(public counter: CounterService) { }
    }

    In the components where you want to retrieve the state data via subscribers, don't forget to extend the StateComponent parent class and use this.autoUnsubscribe() method to automatically unsubscribe the subscribers list:

    import { Component, OnInit } from '@angular/core';
    import { ReplaySubject } from 'rxjs';
    import { StateComponent } from '@ridder/state';
    import { CounterState } from '../../model/counter.service';
    import { StoreService } from '../../model/store.service';
     
    @Component({
      selector: 'app-counter',
      templateUrl: './counter.component.html',
      styleUrls: ['./counter.component.css']
    })
    export class CounterComponent extends StateComponent implements OnInit {
      private counter$: ReplaySubject<CounterState>; // used for async pipe
      private counterValue: number; // used as subscriber
     
      constructor(private store: StoreService) {
        super();
      }
     
      ngOnInit() {
        this.counter$ = this.store.counter.getState();
     
        // unsubscribe automatically on ngOdDestroy
        this.autoUnsubscribe(this.store.counter.getState()
          .subscribe((counterData: CounterState) => {
            this.counterValue = counterData.value;
          }));
      }
     
      increment() {
        this.store.counter.increment();
      }
     
      decrement() {
        this.store.counter.decrement();
      }
    }

    and use the data in your template as subscribers or via Angular async pipe:

    <div>
      <h4>Counter value: {{counterValue}}</h4>
      <input type="button" value="Increment" (click)="increment()">
      <input type="button" value="Decrement" (click)="decrement()">
     
      <h4>
        Counter value (with async pipe): {{(counter$ | async).value}}
      </h4>
     
      <h4 *ngIf="counter$ | async as counter">
        Counter value (with async pipe and ngIf AS syntax ): {{counter.value}}
      </h4>
    </div>

    4. Methods

    StateModel class

    protected getSubject(): ReplaySubject

    Creates and returns the ReplaySubject object for the current state model.

    Return:
    Method returns the ReplaySubject object.

    protected set(data: T): void

    Set/publish new data through the ReplaySubject object associated with the current state model.

    Parameters:
    data - data which should be published via ReplaySubject object.

    Return:
    Method returns nothing - void.

    protected get(): ReplaySubject

    Retrieves the ReplaySubject object associated with the current state model.

    Return:
    Method returns the ReplaySubject object associated to the given eventName.

    StateComponent class

    protected autoUnsubscribe(subscription: Subscription): void

    Add the subscription parameter into the subscription list rxSubscriptions$ which will be unsubscribed and destroyed on ngOnDestroy() lifecycle hook event.

    Parameters:
    subscription - subscription which should be added into the list.

    Return:
    Method returns nothing - void.

    public ngOnDestroy(): void

    Unsubscribe all the subscriptions from the rxSubscriptions$ list and destroy them on ngOnDestroy() lifecycle hook event.

    Return:
    Method returns nothing - void.

    5. Git repository

    https://github.com/dtxprs/state

    6. Run tests

    To run the unit tests, use this command:

    ng test --code-coverage --project=state
    

    Current test coverage is 100%!

    7. Build

    To build the final package run this command:

    ng build state
    

    The build process will generate the packed sources into the dist folder.

    8. Publish to npm

    To publish the new version to npm, go into the dist folder:

    cd ./dist/state
    

    and publish it to npm:

    npm publish --access public
    

    9. Version

    1.0.4

    Install

    npm i @ridder/state

    DownloadsWeekly Downloads

    0

    Version

    1.0.4

    License

    MIT

    Unpacked Size

    41.4 kB

    Total Files

    23

    Last publish

    Collaborators

    • ridder