Discover how to keep your app's data fresh and consistent without rewriting the same code again and again!
Why Selectors for derived state in Angular? - Purpose & Use Cases
Start learning this pattern below
Jump into concepts and practice - no test required
Imagine you have a big list of user data and you want to show only the active users in your app. You try to filter this list manually every time the data changes.
Manually filtering data everywhere is slow and messy. You might forget to update all places, causing bugs and inconsistent views. It's like rewriting the same recipe over and over, risking mistakes.
Selectors let you define one place to compute this filtered list. Angular automatically updates the filtered data whenever the original data changes, keeping your app fast and consistent.
const activeUsers = users.filter(u => u.active); // repeated in many componentsconst selectActiveUsers = createSelector(selectUsers, users => users.filter(u => u.active));
You get a single source of truth for derived data that updates automatically and efficiently across your app.
In a shopping app, showing only items in stock without rewriting filtering logic in every component.
Manual filtering is repetitive and error-prone.
Selectors centralize derived data logic.
Angular updates derived state automatically and efficiently.
Practice
createSelector in Angular state management?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]
- Confusing selectors with actions or reducers
- Thinking selectors modify state
- Assuming selectors handle side effects
createSelector?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]
- Swapping input selectors and projector function order
- Using incorrect property like count or size()
- Calling methods instead of accessing properties
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}]?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]
- Including false done items in result
- Returning original list without filtering
- Confusing filter condition logic
const selectUsers = (state) => state.users;
const selectActiveUsers = createSelector(selectUsers, users => users.active);
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]
- Assuming users is an object, not an array
- Trying to access properties on arrays directly
- Misunderstanding projector function role
Given:
const selectTasks = (state) => state.tasks;
Which of the following
createSelector implementations correctly derives this data?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]
- Missing parentheses around object literal
- Returning array instead of object
- Accessing undefined properties
