Quick Start

app.config.ts

import {provideStore} from '@ngxs/store';
import {provideNgxsDataPlugin} from '@angular-ru/ngxs';

export const appConfig: ApplicationConfig = {
  providers: [
    // ..
    provideStore([AppState]),
    provideNgxsDataPlugin(),
  ],
};

count.state.ts

import {NgxsDataRepository} from '@angular-ru/ngxs/repositories';
import {Computed, DataAction, StateRepository} from '@angular-ru/ngxs/decorators';
import {State} from '@ngxs/store';
// ..

export interface CountModel {
  val: number;
}

@StateRepository()
@State({
  name: 'count',
  defaults: {val: 0},
})
@Injectable()
export class CountState extends NgxsDataRepository<CountModel> {
  @Computed()
  public get values$() {
    return this.state$.pipe(map((state) => state.countSub));
  }

  @DataAction()
  public increment(): void {
    this.ctx.setState((state) => ({val: state.val + 1}));
  }

  @DataAction()
  public decrement(): void {
    this.ctx.setState((state) => ({val: state.val - 1}));
  }

  @Debounce()
  @DataAction()
  public setValueFromInput(@Payload('value') val: string | number): void {
    this.ctx.setState({val: parseFloat(val) || 0});
  }
}

app.component.ts

@Component({
  selector: 'app',
  template: `
    <b class="title">Selection:</b>
    counter.state$ = {{ counter.state$ | async | json }}
    <br />
    counter.values$ = {{ counter.values$ | async }}
    <br />

    <b class="title">Actions:</b>
    <button (click)="counter.increment()">increment</button>
    <button (click)="counter.decrement()">decrement</button>
    <button (click)="counter.reset()">reset</button>

    <b class="title">ngModel:</b>
    <input
      [ngModel]="counter.snapshot"
      (ngModelChange)="counter.setValueFromInput($event)"
    />

    (delay: 300ms)
  `,
})
export class AppComponent {
  constructor(public counter: CountState) {}
}

Debugging

Can be debugged using NGXS logger plugin.

import {withNgxsLoggerPlugin} from '@ngxs/logger-plugin';
import {provideStore, withNgxsNoopExecutionStrategy} from '@ngxs/store';

export const appConfig: ApplicationConfig = {
  providers: [
    provideStore([AppState], withNgxsLoggerPlugin(), withNgxsNoopExecutionStrategy()),
    // ...
  ],
};
@StateRepository()
@State<string[]>({
  name: 'todo',
  defaults: [],
})
@Injectable()
export class TodoState extends NgxsDataRepository<string[]> {
  @DataAction()
  public addTodo(@Payload('todo') todo: string): void {
    if (todo) {
      this.ctx.setState((state) => state.concat(todo));
    }
  }

  @DataAction()
  public removeTodo(@Payload('idx') idx: number): void {
    this.ctx.setState((state) => state.filter((_: string, index: number): boolean => index !== idx));
  }
}

Last updated