NgRx Auto-Entity
Primary version
Primary version
  • NgRx Auto-Entity
  • Getting Started
    • Installation
    • Quick Start
    • Use your State!
      • Enhancing your Facade
      • Simplify your Component
    • From Scratch
      • App Interfaces
      • App Reducer
      • App State Module
      • Entity Model
      • Entity State
      • Update App State
      • Entity Service
      • Update App Module
  • Advanced Topics
    • Advanced Usage
      • Paradigm Changes
        • Models
        • Services
        • Service Providers
      • Taking Control
        • Integrating Custom Effects
      • Building Your Entities
        • Entity Names
        • Sort Comparers
        • Data Transforms
      • Building Your Entity States
        • The buildState() function
        • The buildFeatureState() function
        • The IEntityState Interface
        • The Selector Map
      • Generic Actions
        • Actions Now
        • Reusable Generic Actions
        • Custom Criteria
        • Loading Actions
          • Loading Entities
          • Loading Pages
          • Loading Ranges
        • Optional Loading
        • CURD Actions
        • Utility Actions
      • Correlation
      • Common Selectors
        • Exporting Selectors
      • Extra Selectors
      • Custom Selectors
        • Adding to Facades
        • Using Custom Selectors
      • Custom Effects
        • Composing Actions
        • Workflows
    • Leveraging Facades
      • Preparing Facades
      • The Interface: Selections
        • Using Facade Selections
        • Simplifying Further
      • The Interface: Activities
        • Using Facade Activities
      • So Little Code!
    • Utility Functions
      • Prototyping your Entities
        • Entity Making Performance
      • Entity Name Utilities
      • Entity Key Utilities
      • Entity Comparers
  • Examples
    • Sample Application
      • App Module
      • State
      • Models
      • Services
      • Facades
      • Container Components
      • Presentation Components
      • Modal Component
  • Documentation
    • Reference
  • Extras
    • Github Link
Powered by GitBook
On this page
  • Default Comparer
  • Named Comparers
  • Default Named Comparer
Export as PDF
  1. Advanced Topics
  2. Advanced Usage
  3. Building Your Entities

Sort Comparers

Sorting is a core feature of most applications that use data. At one point or another, you will likely want to display your data sorted in one order or another. Auto-Entity provides built in functionality for sorting your entities. The most common use case would be to define a default comparer, however auto-entity also supports defining additional named comparers to sort your entities in any number of ways.

Default Comparer

To attach a default comparer to your entity, use the comparer property of the configuration object you pass to the @Entity decorator. This is a standard comparer function that you should be familiar with for standard JavaScript sort functionality.

import { Entity } from '@briebug/ngrx-auto-entity'

 @Entity('Customer', { 
   comparer: (a, b) => a.name?.localeCompare(b.name)
 })
 export class Customer {
   @Key id: number;
   name: string;
 }

Sort comparers may be defined directly within the @Entity decorator, or may be defined as a constant or function and passed in the decorator. This allows a single comparer to be used for multiple entities, as appropriate:

import { Entity } from '@briebug/ngrx-auto-entity'

export interface HasName {
  name: string;
}

export const compareName = (a: HasName, b: HasName) => a.name?.localeCompare(b.name)

@Entity('Customer', { 
  comparer: compareName
})
export class Customer {
  @Key id: number;
  name: string;
  // ...
}

@Entity('Supplier', { 
  comparer: compareName
})
export class Supplier {
  @Key id: number;
  name: string;
  // ...
}

Named Comparers

If you find yourself in a situation where you need to sort entities in more than one way, then you can define named comparers. Named comparers are used with the the CustomSorted selector, which is a parameterized selector. Being parameterized, each time you use it with a different parameter, its memoized result is recomputed. This ensures that you don't use too much memory when sorting the same set of entities in different ways, however at greater compute cost.

To define named comparers, use the comparers property of the configuration object you pass to the @Entity decorator. This property expects an object, or an associative map, where the properties are the names of the comparers, and the value of each property is the comparer function.

import { Entity } from '@briebug/ngrx-auto-entity'

export interface HasNumericId {
  id: number;
}

export const compareId = (a: HasNumericId, b: HasNumericId) => 
  a.id - b.id;

export interface HasName {
  name: string;
}

export const compareName = (a: HasName, b: HasName) =>
  a.name?.localeCompare(b.name)

@Entity('Customer', { 
  comparer: compareName,
  comparers: {
    byId: compareId,
    byDateAcquiredDesc: (a, b) => b.dateAcquired - a.dateAcquired
  }
})
export class Customer {
  @Key id: number;
  name: string;
  dateAcquired: Date;
  // ...
}

@Entity('Supplier', { 
  comparer: compareName,
  comparers: {
    byId: compareId,
    byLastShipment: (a, b) => a.dateOfLastShipment - b.dateOfLastShipment
  }
})
export class Supplier {
  @Key id: number;
  name: string;
  dateOfLastShipment: Date;
  // ...
}

Default Named Comparer

When defining named comparers, you may also define the default within the comparers property of the configuration object passed to @Entity. This is an alternative method of defining a default comparer.

import { Entity } from '@briebug/ngrx-auto-entity'

export interface HasName {
  name: string;
}

export const compareName = (a: HasName, b: HasName) =>
  a.name?.localeCompare(b.name)

@Entity('Customer', { 
  comparers: {
    default: compareName,
  }
})
export class Customer {
  @Key id: number;
  name: string;
  // ...
}

Note that when defining default comparers, if you define both the comparer property as well as the default named comparer of the comparers property, the comparer defined on the comparer property will always take precedence. As such, this configuration will sort by name, not id:

import { Entity } from '@briebug/ngrx-auto-entity';

export interface HasNumericId {
  id: number;
}

export const compareId = (a: HasNumericId, b: HasNumericId) => 
  a.id - b.id;

export interface HasName {
  name: string;
}

export const compareName = (a: HasName, b: HasName) =>
  a.name?.localeCompare(b.name)

@Entity('Customer', { 
  comparer: compareName,
  comparers: {
    default: compareId,
  }
})
export class Customer {
  @Key id: number;
  name: string;
  // ...
}
PreviousEntity NamesNextData Transforms

Last updated 4 years ago

To get a named comparer for an entity, you can use the comparer . Further, you can use the customSorted selector and pass the name of the comparer you wish to use for the sort, which will sort with that comparer on selection.

Utility Functions