Selectors help you get specific pieces of data from your app's state. They can also create new data by combining or changing existing state values.
Selectors for derived state in Angular
Start learning this pattern below
Jump into concepts and practice - no test required
or
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Introduction
Syntax
Angular
import { createSelector } from '@ngrx/store'; const selectFeature = (state) => state.feature; const selectDerived = createSelector( selectFeature, (feature) => { // return derived data here } );
createSelector takes one or more selectors as input and a function that returns new data.
The function runs only when input data changes, improving performance.
Examples
Angular
const selectItems = (state) => state.items; const selectItemCount = createSelector( selectItems, (items) => items.length );
Angular
const selectUser = (state) => state.user; const selectSettings = (state) => state.settings; const selectUserProfile = createSelector( selectUser, selectSettings, (user, settings) => ({ name: user.name, theme: settings.theme }) );
Sample Program
This Angular component shows a shopping cart list and the total price. The total price is calculated using a selector that sums item prices times quantities.
Angular
import { Component } from '@angular/core'; import { createSelector } from '@ngrx/store'; interface AppState { cart: { items: { name: string; price: number; quantity: number }[] }; } const state: AppState = { cart: { items: [ { name: 'Apple', price: 1, quantity: 3 }, { name: 'Banana', price: 2, quantity: 2 } ] } }; const selectCartItems = (state: AppState) => state.cart.items; const selectTotalPrice = createSelector( selectCartItems, (items) => items.reduce((total, item) => total + item.price * item.quantity, 0) ); @Component({ selector: 'app-cart', standalone: true, template: ` <h2>Shopping Cart</h2> <ul> <li *ngFor="let item of items">{{item.name}} x{{item.quantity}} - ${{item.price}}</li> </ul> <p><strong>Total: ${{total}}</strong></p> ` }) export class CartComponent { items = state.cart.items; total = selectTotalPrice(state); }
Important Notes
Selectors help keep your UI code clean by moving data logic out of components.
Using selectors improves performance because they only recalculate when needed.
Summary
Selectors get and create data from your app state.
They help avoid repeating code and improve performance.
Use createSelector with input selectors and a function to make derived data.
Practice
1. What is the main purpose of using
createSelector in Angular state management?easy
Solution
Step 1: Understand what
createSelectordoescreateSelectoris used to create selectors that compute derived data from the state without modifying it.Step 2: Differentiate from other store operations
Modifying state or dispatching actions are done by reducers and actions, not selectors.Final Answer:
To compute derived data from the state efficiently -> Option CQuick Check:
Derived data = createSelector [OK]
Hint: Remember: selectors read and compute, not modify state [OK]
Common Mistakes:
- Confusing selectors with actions or reducers
- Thinking selectors modify state
- Assuming selectors handle side effects
2. Which of the following is the correct syntax to create a selector that derives the total count from a list in the state using
createSelector?easy
Solution
Step 1: Check the order of arguments in
The first argument(s) are input selectors, followed by a projector function.createSelectorStep 2: Verify the projector function logic
The projector function receives the selected data and returns the derived value. Usinglist.lengthcorrectly gets the count.Final Answer:
const selectTotal = createSelector(selectList, list => list.length); -> Option BQuick Check:
Input selectors first, then projector function [OK]
Hint: Input selectors first, projector function last in createSelector [OK]
Common Mistakes:
- Swapping input selectors and projector function order
- Using incorrect property like count or size()
- Calling methods instead of accessing properties
3. Given the following selectors:
What will
const selectItems = (state) => state.items;
const selectCompletedItems = createSelector(selectItems, items => items.filter(item => item.done));
What will
selectCompletedItems return if state.items is [{done: true}, {done: false}, {done: true}]?medium
Solution
Step 1: Understand the input selector
selectItemsreturns the full list of items from state.Step 2: Apply the projector function filter
The projector filters items whereitem.doneis true, so it keeps only those objects.Final Answer:
[{done: true}, {done: true}] -> Option AQuick Check:
Filter done=true items = [{done:true}, {done:true}] [OK]
Hint: Filter returns only items matching condition [OK]
Common Mistakes:
- Including false done items in result
- Returning original list without filtering
- Confusing filter condition logic
4. Identify the error in this selector code:
const selectUsers = (state) => state.users;
const selectActiveUsers = createSelector(selectUsers, users => users.active);
medium
Solution
Step 1: Check the input selector
selectUserscorrectly returnsstate.users, which is valid.Step 2: Analyze the projector function
The projector accessesusers.active, butusersis likely an array, so it should filter or map, not access a property.Final Answer:
The projector function incorrectly accesses users.active instead of filtering -> Option AQuick Check:
Projector must handle data type correctly [OK]
Hint: Check if projector matches data type (array vs object) [OK]
Common Mistakes:
- Assuming users is an object, not an array
- Trying to access properties on arrays directly
- Misunderstanding projector function role
5. You want to create a selector that returns the number of completed tasks and the number of pending tasks from state.
Given:
Which of the following
Given:
const selectTasks = (state) => state.tasks;
Which of the following
createSelector implementations correctly derives this data?hard
Solution
Step 1: Check the syntax of the projector function
const selectTaskCounts = createSelector(selectTasks, tasks => ({ completed: tasks.filter(t => t.done).length, pending: tasks.filter(t => !t.done).length })); returns an object with propertiescompletedandpendingcorrectly using parentheses to return the object literal.Step 2: Identify errors in other options
const selectTaskCounts = createSelector(selectTasks, tasks => { completed: tasks.filter(t => t.done).length, pending: tasks.filter(t => !t.done).length }); lacks parentheses around the object, causing a syntax error. const selectTaskCounts = createSelector(selectTasks, tasks => [tasks.filter(t => t.done).length, tasks.filter(t => !t.done).length]); returns an array, not an object. const selectTaskCounts = createSelector(selectTasks, tasks => tasks.doneCount) accesses a non-existent property.Final Answer:
const selectTaskCounts = createSelector(selectTasks, tasks => ({ completed: tasks.filter(t => t.done).length, pending: tasks.filter(t => !t.done).length })); -> Option DQuick Check:
Use parentheses to return object literals in arrow functions [OK]
Hint: Wrap object in parentheses to return from arrow function [OK]
Common Mistakes:
- Missing parentheses around object literal
- Returning array instead of object
- Accessing undefined properties
