Search code examples
ngrxngrx-entity

NGRX; How to apply filter on adapter data


I have this piece of code which I want to apply a filter on. The state uses EntityState and Adapter. getAllObjects needs to get categories with parentId of 13 and the getAllTextures gets the remaining.

import { Category } from './models/category';
import { createFeatureSelector, createSelector } from '@ngrx/store';
import { AppState } from './app-state';
import { EntityState } from '@ngrx/entity';
import * as fromCategory from './services/reducers/category.reducer';

export interface CategoriesState extends EntityState<Category> {
    allCategoriesLoaded: boolean;
}

const getCategories = createFeatureSelector<AppState, CategoriesState>('categories');

export const getAllObjects = createSelector(getCategories, fromCategory.selectAll); // filter(x => x.parentId === 13)
export const getAllTextures = createSelector(getCategories, fromCategory.selectAll); // filter(x => x.parentId !== 13)
export const getAllCategoriesLoaded = createSelector(getCategories, state => state.allCategoriesLoaded);

and this is the reducer:

import {createReducer, on, State} from '@ngrx/store';
import { EntityState, EntityAdapter, createEntityAdapter } from '@ngrx/entity';
import { Category } from 'src/app/models/category';
import { RefreshCategoryDone, CategoryActionTypes, CategoryActions } from '../actions/category.actions';
import { CategoriesState } from 'src/app/categories-state';


export const categoryAdapter: EntityAdapter<Category> = createEntityAdapter<Category>();
export const initialState: CategoriesState = categoryAdapter.getInitialState({allCategoriesLoaded : false});

export function categoryReducer(state = initialState, action: CategoryActions) {
  switch (action.type) {
      case CategoryActionTypes.LoadCategories:
      categoryAdapter.addMany(action.payload, state);
      break;
    default:
      return state;
  }
}

export const {
  selectAll,
  selectEntities,
  selectIds,
  selectTotal
} = categoryAdapter.getSelectors();

Is it possible to select data from adapter by condition? If so, how?


Solution

  • Found the answer:

    import { Category } from './models/category';
    import { createFeatureSelector, createSelector } from '@ngrx/store';
    import { AppState } from './app-state';
    import { EntityState } from '@ngrx/entity';
    import * as fromCategory from './services/reducers/category.reducer';
    import { map } from 'rxjs/operators';
    
    export interface CategoriesState extends EntityState<Category> {
        allCategoriesLoaded: boolean;
    }
    
    const getCategories = createFeatureSelector<AppState, CategoriesState>('categories');
    
    export const getAllCategories = createSelector(getCategories, fromCategory.selectAll);
    export const getAllObjects = createSelector(getAllCategories, (categories) => categories.filter(x => x.categoryId !== 13));
    export const getAllTextures = createSelector(getAllCategories, (categories) => categories.filter(x => x.categoryId === 13));
    export const getAllCategoriesLoaded = createSelector(getCategories, state => state.allCategoriesLoaded);