Search / Filter State NGXS

Asked by At

I am new to NGXS and trying to integrate it into a small project. The only problem is that there are no good examples of a search / filter on state.

My app gets a list of products from a backend API. It shows them by SKU on the page. I want the user to be able to type in an SKU in the input field and have the list automatically filter products as the user types.


static getProductList(state: ProductStateModel) {
  return state.products;

static prodFilter(searchObj: any[]) {
  // something needs to happen here in order to filter state


@Select(ProductState.getProductList) products: Observable<Product[]>;

filterForm ={ sku: null });

constructor( private store: Store, private fb: FormBuilder ) { }

ngOnInit() { new GetProducts() );

//something in here (ngOnInit? ngOnChanges?) to pass (cloned??) product state into selector??


  <input type='number' formControlName='sku' />
  <button type='submit'>Submit</button>

<mat-accordion class='product-accordion'>
  <mat-expansion-panel *ngFor='let product of products | async'>
      SKU: {{ product.sku }}

    <p>${{ product.price }}</p>
    <p>{{ product.description }}</p>

I have so many questions. I believe that I shouldn't be mutating the products state directly so would I clone it? Would the HTML output change then? Should I create a new state.ts file for the filtered products?

Any help would be much appreciated (especially a stackblitz example)!

1 Answers

Garth Mason On Best Solutions

You might find this easier if you model your state like this, capturing the base products list and the text entered in the search textbox:

export interface ProductsStateModel {
  products: Product[];
  filterText: string; // Your SKU value that is entered

.. Then in your state, use a selector to project out the filtered list that you actually want to display on the UI (filteredProducts).

 name: 'products'
export class ProductsState { 

   static filteredProducts(state: ProductsStateModel) { 
      return state.products.filter(p => p.sku === state.filterText);

   updateFilter({patchState}: StateContext<ProductStateModel>, {payload}: ProductSkuEntered) {
       patchState({ filterText: payload.skuText });


In the UI, you can in your template then subscribe to the selector i.e. in products.component.ts use @Select(ProductsState.filteredProducts) products$.

When the search text changes, you can dispatch an action to the store to update that string in the state i.e. store.dispatch(new ProductSkuEntered({ skuText: enteredText })); The NGXS selector will then automatically update your 'filteredProducts` list to display just those that match the text.

It's also nice to hook up a debounceTime to the change in the text so that you only filter when the user has stopped typing. i.e. only dispatch the ProductSkuEntered after the debounce.

Note: I see you are using the NGXS forms plugin - I don't have experience with that plugin but it is not required for this scenario (although you might be using it elsewhere).