Skip to content

State and feature state

The state is the global object that contains all data to be shared among components and with a lifetime greater than a component's lifetime.

The state contains all the defined feature states.

State
export interface State {
  [key: string]: object;
}

Note

The state must be immutable but, to keep it simple, the state remains a simple javascript object. This is the responsibility of the coder to guarantee immutability of the state.

Static definition of a feature state

The static way of providing a feature state is to use the decorator NgSsmFeatureState.

export const NgSsmFeatureState = (specification: FeatureStateSpecification) => {
  return (target: object) => {
    featureStateSpecifications.push(specification);
  };
};

A feature state can be generated with schematics. For example:

ng g ngssm-schematics:feature-state testFeatureState

with the generated file

import update, { Spec } from 'immutability-helper';

import { NgSsmFeatureState, State } from 'ngssm-store';

export const selectTestFeatureStateState = (state: State): TestFeatureStateState =>
  state[TestFeatureStateStateSpecification.featureStateKey] as TestFeatureStateState;

export const updateTestFeatureStateState = (state: State, command: Spec<TestFeatureStateState, never>): State =>
  update(state, {
    [TestFeatureStateStateSpecification.featureStateKey]: command
  });

export interface TestFeatureStateState {}

@NgSsmFeatureState({
  featureStateKey: TestFeatureStateStateSpecification.featureStateKey,
  initialState: TestFeatureStateStateSpecification.initialState
})
export class TestFeatureStateStateSpecification {
  public static readonly featureStateKey = 'test-feature-state-state';
  public static readonly initialState: TestFeatureStateState = {};
}

Dynamic registration of a feature state

In order to allow associating a feature state to a component and so, to remove that state when the component is destroyed, a feature state could also be registered at any time.

Note

As the static registration of feature state will be removed in a future release, this is the way to register any feature state.

Two actions are provided to register and unregister feature state:

import { Action } from '../action';
import { NgssmStoreActionType } from './ngssm-store-action-type';

export class NgssmRegisterFeatureStateAction implements Action {
  public readonly type: string = NgssmStoreActionType.registerFeatureState;

  constructor(
    public readonly featureStateKey: string,
    public readonly initialValue: object
  ) {}
}

export class NgssmUnregisterFeatureStateAction implements Action {
  public readonly type: string = NgssmStoreActionType.unregisterFeatureState;

  constructor(public readonly featureStateKey: string) {}
}

When using a global feature state, one can use the function provideNgssmFeatureState as follows

export const appConfig: ApplicationConfig = {
  providers: [provideNgssmFeatureState('my-feature-state', { description: 'something' })]
};

When using a feature state with a component lifetime, one can use the directive ProvideNgssmFeatureStateDirective as follows

import { Component } from '@angular/core';
import { ProvideNgssmFeatureStateDirective } from './provide-ngssm-feature-state.directive';
import { FeatureStateSpecification, NGSSM_COMPONENT_WITH_FEATURE_STATE } from './feature-state-specification';

@Component({
  selector: 'ngssm-provide-ngssm-feature-state-directive-test',
  imports: [],
  template: ` <p>provide-ngssm-feature-state-directive-test works!</p> `,
  styles: ``,
  hostDirectives: [ProvideNgssmFeatureStateDirective],
  providers: [
    {
      provide: NGSSM_COMPONENT_WITH_FEATURE_STATE,
      multi: false,
      useExisting: ProvideNgssmFeatureStateDirectiveTestComponent
    }
  ]
})
export class ProvideNgssmFeatureStateDirectiveTestComponent implements FeatureStateSpecification {
  featureStateKey = 'my-feature-state';

  initialState = {
    id: 'testing'
  };
}