Angular NgRx Selectors

Learn Angular NgRx Selectors with createSelector, memoization, feature selectors, composed selectors, Signals integration, enterprise architecture, best practices, and interview questions.

In NgRx, components should never read the Store directly.

Instead, they use Selectors, which provide a clean, reusable, and efficient way to retrieve data from the Store.

Selectors are one of the most powerful features of NgRx because they:

  • Encapsulate state access
  • Improve performance through memoization
  • Prevent duplicate logic
  • Support derived state
  • Make applications easier to test
  • Improve maintainability

In enterprise applications, almost every component interacts with the Store through Selectors.


Table of Contents

  • What are Selectors?
  • Why Use Selectors?
  • Selector Architecture
  • Feature Selectors
  • createSelector()
  • Memoization
  • Derived State
  • Composing Selectors
  • Selectors with Signals
  • Enterprise Banking Example
  • Performance Best Practices
  • Common Mistakes
  • Top 10 Interview Questions
  • Summary

What are Selectors?

A Selector is a pure function that retrieves a portion of application state from the Store.

Instead of components navigating the Store structure,

components simply request the data they need.

Example

customers$ = this.store.select(selectCustomers);

The component doesn't know how the Store is organized.


Why Use Selectors?

Without Selectors

  • Components access Store structure directly
  • Duplicate filtering logic
  • Harder maintenance
  • Difficult refactoring

With Selectors

  • Encapsulated state access
  • Reusable logic
  • Memoized results
  • Cleaner components
  • Better performance

Selector Architecture

flowchart LR

Store

Store --> FeatureSelector

FeatureSelector --> Selector

Selector --> Component

Component --> UI

Store Read Flow

flowchart TD

Store

Store --> Selector

Selector --> Observable

Observable --> Component

Component --> Template

Feature Selectors

A Feature Selector retrieves an entire feature state.

Example

export interface CustomerState {

  customers: Customer[];

  loading: boolean;

}

Create Feature Selector

import { createFeatureSelector } from '@ngrx/store';

export const selectCustomerState =

createFeatureSelector<CustomerState>(

'customer'

);

This becomes the foundation for other selectors.


createSelector()

Most Selectors are created using createSelector().

Example

import { createSelector } from '@ngrx/store';

export const selectCustomers =

createSelector(

selectCustomerState,

state => state.customers

);

Components can now retrieve customer data without understanding the Store structure.


Selector Flow

flowchart LR

Store

Store --> FeatureSelector

FeatureSelector --> createSelector

createSelector --> Component

Reading Data

Component

customers$ =

this.store.select(

selectCustomers

);

Template

<ul>

<li

*ngFor="let customer of customers$ | async">

{{ customer.name }}

</li>

</ul>

Memoization

Selectors are memoized.

This means Angular recalculates the selector only when its input state changes.

Benefits

  • Better performance
  • Fewer computations
  • Faster rendering
  • Reduced CPU usage

Memoization Architecture

flowchart LR

StoreChange

StoreChange --> Selector

Selector --> Cache

Cache --> Component

If the input state remains the same,

the cached value is returned.


Derived State

Selectors can compute values instead of storing them.

Example

export const selectCustomerCount =

createSelector(

selectCustomers,

customers => customers.length

);

Instead of storing:

customerCount

inside the Store,

compute it when needed.


Derived Data Examples

Useful derived values

  • Total Orders
  • Customer Count
  • Account Balance
  • Shopping Cart Total
  • Active Users
  • Filtered Products

Composing Selectors

Selectors can be combined.

Example

export const selectPremiumCustomers =

createSelector(

selectCustomers,

customers =>

customers.filter(

customer => customer.isPremium

)

);

Another example

export const selectPremiumCount =

createSelector(

selectPremiumCustomers,

customers => customers.length

);

This keeps logic reusable and modular.


Composed Selector Architecture

flowchart TD

Store

Store --> selectCustomers

selectCustomers --> PremiumCustomers

PremiumCustomers --> PremiumCount

PremiumCount --> Component

Parameterized Selectors

Selectors can accept parameters using factory functions.

export const selectCustomerById =

(id: number) =>

createSelector(

selectCustomers,

customers =>

customers.find(

customer => customer.id === id

)

);

Usage

customer$ =

this.store.select(

selectCustomerById(101)

);

Selectors with Signals

Modern Angular integrates Selectors with Signals.

import { toSignal } from '@angular/core/rxjs-interop';

customers =

toSignal(

this.store.select(

selectCustomers

)

);

Template

@for (

customer of customers();

track customer.id

) {

<div>

{{ customer.name }}

</div>

}

Benefits

  • Cleaner templates
  • Signal reactivity
  • Automatic updates

Signals Architecture

flowchart LR

Store

Store --> Selector

Selector --> Signal

Signal --> Component

Component --> UI

Enterprise Banking Example

Banking Dashboard

Store

  • Customers
  • Accounts
  • Cards
  • Loans
  • Transactions
  • Investments

Selectors

  • Active Accounts
  • Total Balance
  • Premium Customers
  • Recent Transactions
  • Loan Summary

Architecture

flowchart TD

Store

Store --> AccountSelector

Store --> CustomerSelector

Store --> TransactionSelector

AccountSelector --> Dashboard

CustomerSelector --> Dashboard

TransactionSelector --> Dashboard

Benefits

  • Centralized business logic
  • Better reuse
  • Excellent performance
  • Easier testing

Folder Structure

store/

├── selectors/
│
├── customer.selectors.ts
│
├── account.selectors.ts
│
├── auth.selectors.ts
│
├── order.selectors.ts
│
└── index.ts

Performance Best Practices

Practice Benefit
Always use Selectors Encapsulation
Use Feature Selectors Better modularity
Derive values Less duplicate state
Compose Selectors Better reuse
Use memoization Improved performance
Convert to Signals Cleaner templates
Use OnPush Better rendering
Keep Selectors pure Predictable behavior

Common Mistakes

Accessing Store Directly

❌ Wrong

this.store.customer.customers

Always use Selectors.


Storing Derived Data

❌ Wrong

Store:

customerCount

Better

customers.length

inside a Selector.


Business Logic in Components

❌ Wrong

customers$

.pipe(

map(customers =>

customers.filter(

customer => customer.active

)

)

);

Move the filtering into a Selector.


Side Effects in Selectors

Selectors should never:

  • Call APIs
  • Update state
  • Dispatch Actions

Selectors are pure functions.


Large Selectors

Split complex logic into smaller composed Selectors.


Feature Selector vs Selector

Feature Feature Selector Selector
Reads Feature State
Reads Specific Data
Uses createFeatureSelector
Uses createSelector
Composable Limited Excellent

Advantages

Feature Benefit
Memoization Faster performance
Encapsulation Cleaner components
Derived State Less duplicate data
Composition Better reuse
Signals Integration Modern Angular support
Enterprise Ready Highly scalable

Top 10 Selectors Interview Questions

1. What is a Selector in NgRx?

Answer

A Selector is a pure function that retrieves and derives state from the NgRx Store without modifying it.


2. Why should components use Selectors?

Answer

Selectors encapsulate Store access, improve reusability, enable memoization, and keep components simple and maintainable.


3. What is a Feature Selector?

Answer

A Feature Selector retrieves an entire feature slice of state and serves as the starting point for creating more specific selectors.


4. What does createSelector() do?

Answer

createSelector() creates memoized selectors that efficiently compute and return specific pieces of application state.


5. What is memoization?

Answer

Memoization caches the previous selector result and recomputes it only when its input state changes, reducing unnecessary calculations.


6. What is derived state?

Answer

Derived state is data calculated from existing Store values, such as totals, counts, filtered lists, or summaries, instead of storing duplicate values.


7. Can Selectors be composed?

Answer

Yes. Multiple selectors can be combined to build more advanced selectors while keeping logic modular and reusable.


8. Can Selectors work with Signals?

Answer

Yes. Selector Observables can be converted into Signals using toSignal() for a more modern and reactive template experience.


9. What are common Selector mistakes?

Answer

  • Accessing Store directly
  • Storing derived data
  • Adding business logic to components
  • Performing side effects in selectors
  • Creating overly complex selectors

10. What are Selector best practices?

Answer

Use Feature Selectors, derive values instead of storing duplicates, compose selectors for reuse, keep selectors pure, leverage memoization, and integrate them with Signals where appropriate.


Interview Cheat Sheet

Requirement Recommended Solution
Read Store State Selector
Read Feature State Feature Selector
Derived Values createSelector()
Performance Memoization
Reusable Logic Composed Selectors
UI Reactivity Signals
Change Detection OnPush
Global State NgRx Store
Async Work Effects
Enterprise Apps Feature Selectors + Memoized Selectors

Summary

NgRx Selectors provide the recommended way to read application state by encapsulating Store access behind reusable, memoized, and composable functions. They simplify components, avoid duplicate business logic, and improve performance through memoization. In modern Angular applications, Selectors are often combined with Signals to deliver a clean, reactive, and highly maintainable architecture suitable for enterprise-scale applications.


Key Takeaways

  • ✔ Always use Selectors to read Store data.
  • ✔ Use Feature Selectors as the foundation for feature state.
  • ✔ Create memoized Selectors with createSelector().
  • ✔ Compute derived state instead of storing duplicate values.
  • ✔ Compose Selectors to build reusable business logic.
  • ✔ Keep Selectors pure and free of side effects.
  • ✔ Convert Selector Observables to Signals for modern Angular templates.
  • ✔ Organize Selectors by feature module.
  • ✔ Combine Selectors with OnPush Change Detection for optimal performance.
  • ✔ Selectors are one of the most frequently discussed NgRx interview topics.

Next Article

➡️ 100-NgRx-Entity-QA.md