LogoLogo
v18.0
v18.0
  • NGXS
    • Overview
  • INTRODUCTION
    • WHY
    • INSTALLATION
    • STARTER KIT
    • SCHEMATICS
  • CONCEPTS
    • STORE
      • Overview
      • Store Schematics
      • Store Options
      • Error Handling
      • Meta Reducers
    • ACTIONS
      • Overview
      • Action Schematics
      • Actions Life Cycle
      • Action Handlers
      • Cancellation
      • Monitoring Unhandled Actions
    • STATE
      • Overview
      • State Schematics
      • Life-cycle
      • Composition
      • Lazy Loading
      • State Operators
      • Custom State Operators
      • Shared State
      • State Token
      • Immutability Helpers
      • Error Handling
      • Sub States
    • SELECT
      • Overview
      • Mapped Sub States
      • Optimizing Selectors
      • Selector Utils
      • Error Handling
      • Signals
      • Select Decorator
  • STYLE GUIDE
  • PLUGINS
    • Overview
    • CLI
    • Logger
    • Devtools
    • Storage
    • Forms
    • Web Socket
    • Router
    • HMR
  • RECIPES
    • Authentication
    • Caching
    • Component Events from NGXS
    • Debouncing Actions
    • Dynamic Plugins
    • Module Federation
    • Unit Testing
    • RxAngular Integration
    • Waiting For App Stability
  • COMMUNITY & LABS
    • COMMUNITY
      • FAQ
      • Resources
      • Contributors
      • Contributing
      • Sponsors
    • NGXS LABS
      • Overview
  • DEPRECATIONS
    • Inject Container State Deprecation
    • Sub States Deprecation
    • Select Decorator Deprecation
  • CHANGELOG
Powered by GitBook
On this page
  1. CONCEPTS
  2. SELECT

Mapped Sub States

NGXS provides the ability to merge multiple dynamic selectors into one.

Let's look at the code below:

interface Animal {
  type: string;
  age: string;
  name: string;
}

@State<Animal[]>({
  name: 'animals',
  defaults: [
    { type: 'zebra', age: 'old', name: 'Ponny' },
    { type: 'panda', age: 'young', name: 'Jimmy' }
  ]
})
@Injectable()
export class ZooState {
  static getPandas(age: string) {
    return createSelector([ZooState], (state: Animal[]) => {
      return state.filter(animal => animal.type === 'panda' && animal.age === age);
    });
  }

  static getZebras(age: string) {
    return createSelector([ZooState], (state: Animal[]) => {
      return state.filter(animal => animal.type === 'zebra' && animal.age === age);
    });
  }

  static getPandasAndZebras(age: string) {
    return createSelector(
      [ZooState.pandas(age), ZooState.zebras(age)],
      (pandas: Animal[], zebras: Animal[]) => {
        return [pandas, zebras];
      }
    );
  }
}

This construct will merge 2 dynamic selectors and memoize the result.

Another example could be multiple Zoos in our application:

interface Animal {
  type: string;
  age: string;
  name: string;
}

interface ZooStateModel {
  [id: string]: {
    animals: Animal[];
    ageFilter: string;
  };
}

@State<ZooStateModel>({
  name: 'animals',
  defaults: {
    zoo1: {
      ageFilter: 'young',
      animals: [
        { type: 'zebra', age: 'old', name: 'Ponny' },
        { type: 'panda', age: 'young', name: 'Jimmy' }
      ]
    }
  }
})
@Injectable()
export class ZooState {
  static getZooAnimals(zooName: string) {
    return createSelector([ZooState], (state: ZooStateModel) => state[zooName].animals);
  }

  static getPandas(zooName: string) {
    return createSelector([ZooState.getZooAnimals(zooName)], (state: Animal[]) => {
      return state.filter(animal => animal.type === 'panda' && animal.age === 'young');
    });
  }

  static getPandasWithoutMemoize(zooName: string) {
    return createSelector([ZooState], (state: ZooStateModel) => {
      return state[zooName].animals.filter(
        animal => animal.type === 'panda' && animal.age === 'young'
      );
    });
  }
}

In that example merging is required to avoid unnecessary store events. When we subscribe to Zoo.getPandasWithoutMemoize store will dispatch event whenever ZooState will change (even ZooState.getAgeFilter), but when subscribing to Zoo.getPandas store will dispatch event only if result has been changed.

PreviousSELECTNextOptimizing Selectors

Last updated 9 months ago