Custom State Operators

In this section you will find state operators that are not part of the library but can be very helpful in your app.

upsertItem

Inserts or updates an item in an array depending on whether it exists.

Usage

ctx.setState(
  patch<FoodModel>({
    foods: upsertItem<Food>(f => f.id === foodId, food)
  })
);

State Operator Code

import { StateOperator } from '@ngxs/store';
import {
  compose,
  iif,
  insertItem,
  NoInfer,
  patch,
  Predicate,
  updateItem
} from '@ngxs/store/operators';

export function upsertItem<T>(
  selector: number | Predicate<T>,
  upsertValue: NoInfer<T>
): StateOperator<T[]> {
  return compose<T[]>(
    items => <T[]>(items || []),
    iif<T[]>(
      items => Number(selector) === selector,
      iif<T[]>(
        items => selector < items.length,
        updateItem(selector, patch(upsertValue)),
        insertItem(upsertValue, <number>selector)
      ),
      iif<T[]>(
        items => items.some(<Predicate<T>>selector),
        updateItem(selector, patch(upsertValue)),
        insertItem(upsertValue)
      )
    )
  );
}

Collaborate with your awesome operator!

Have you identified an use case for a new operator? If that's the case you can collaborate sharing it here! To learn more read this issue and submit your PR with your operator as part of the Snippets section.

Last updated