Bird
Raised Fist0
Angularframework~10 mins

NgRx store concept in Angular - Interactive Code Practice

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Practice - 5 Tasks
Answer the questions below
1fill in blank
easy

Complete the code to import the NgRx StoreModule in an Angular standalone component.

Angular
import { StoreModule } from '@ngrx/store';

@Component({
  standalone: true,
  imports: [StoreModule.[1]({})],
  selector: 'app-root',
  template: `<h1>Welcome</h1>`
})
export class AppComponent {}
Drag options to blanks, or click blank then click option'
AforFeature
BcreateStore
CprovideStore
DforRoot
Attempts:
3 left
💡 Hint
Common Mistakes
Using forFeature instead of forRoot in the root component.
Trying to use createStore which is not a StoreModule method.
2fill in blank
medium

Complete the code to select a piece of state from the store using a selector.

Angular
this.userName$ = this.store.select([1]);
Drag options to blanks, or click blank then click option'
AfetchUserName
BgetUserName
CselectUserName
DloadUserName
Attempts:
3 left
💡 Hint
Common Mistakes
Using verbs like get or fetch which are not typical selector names.
Trying to call the selector instead of passing it as a reference.
3fill in blank
hard

Fix the error in dispatching an action to the store.

Angular
this.store.[1](loadItems());
Drag options to blanks, or click blank then click option'
Atrigger
Bdispatch
Csend
Demit
Attempts:
3 left
💡 Hint
Common Mistakes
Using non-existent methods like emit or send.
Confusing dispatch with select.
4fill in blank
hard

Fill both blanks to define a reducer function with initial state and action handling.

Angular
export const counterReducer = createReducer(
  [1],
  on(increment, state => ({ count: state.count [2] 1 }))
);
Drag options to blanks, or click blank then click option'
A{ count: 0 }
B+
C-
D0
Attempts:
3 left
💡 Hint
Common Mistakes
Using a number instead of an object for initial state.
Using subtraction instead of addition for increment.
5fill in blank
hard

Fill all three blanks to create a feature store module with a reducer and selector.

Angular
StoreModule.[1]('counter', [2]),

export const selectCounter = createFeatureSelector<CounterState>('[3]');
Drag options to blanks, or click blank then click option'
AforFeature
BcounterReducer
Ccounter
DforRoot
Attempts:
3 left
💡 Hint
Common Mistakes
Using forRoot instead of forFeature for feature modules.
Mismatching feature names in selector and module.

Practice

(1/5)
1. What is the primary purpose of the NgRx Store in an Angular application?
easy
A. To style components with CSS dynamically
B. To handle HTTP requests and responses automatically
C. To keep all application data in one central place for easy access and updates
D. To manage routing between different pages

Solution

  1. Step 1: Understand NgRx Store role

    The NgRx Store is designed to hold the application state in one place.
  2. Step 2: Compare with other options

    Options B, C, and D describe other Angular features, not the store's purpose.
  3. Final Answer:

    To keep all application data in one central place for easy access and updates -> Option C
  4. Quick Check:

    NgRx Store = Central app data storage [OK]
Hint: NgRx Store = single source of truth for app data [OK]
Common Mistakes:
  • Confusing store with routing or HTTP services
  • Thinking store manages styles or UI directly
2. Which of the following is the correct way to dispatch an action named loadItems using NgRx Store in a component?
easy
A. this.store.call(loadItems);
B. this.store.emit(loadItems);
C. store.dispatch = loadItems();
D. this.store.dispatch(loadItems());

Solution

  1. Step 1: Recall NgRx dispatch syntax

    Actions are dispatched by calling this.store.dispatch(action()).
  2. Step 2: Check other options for syntax errors

    Options A, B, and C use incorrect methods or assignment instead of dispatch call.
  3. Final Answer:

    this.store.dispatch(loadItems()); -> Option D
  4. Quick Check:

    Dispatch action = this.store.dispatch(action()) [OK]
Hint: Dispatch actions with this.store.dispatch(action()) [OK]
Common Mistakes:
  • Using emit or call instead of dispatch
  • Assigning dispatch instead of calling it
3. Given this reducer snippet:
const initialState = { count: 0 };
function counterReducer(state = initialState, action) {
  switch(action.type) {
    case 'increment':
      return { count: state.count + 1 };
    case 'decrement':
      return { count: state.count - 1 };
    default:
      return state;
  }
}

What will be the state after dispatching { type: 'increment' } twice starting from initial state?
medium
A. { count: 0 }
B. { count: 2 }
C. { count: 1 }
D. { count: -2 }

Solution

  1. Step 1: Analyze reducer behavior for 'increment'

    Each 'increment' action adds 1 to the current count.
  2. Step 2: Apply two increments starting from 0

    0 + 1 = 1 after first increment, then 1 + 1 = 2 after second increment.
  3. Final Answer:

    { count: 2 } -> Option B
  4. Quick Check:

    Two increments = count 2 [OK]
Hint: Add 1 per 'increment' action to count [OK]
Common Mistakes:
  • Counting only one increment
  • Confusing decrement with increment
4. Identify the error in this NgRx reducer code:
function todoReducer(state = [], action) {
  if (action.type === 'add') {
    state.push(action.payload);
    return state;
  }
  return state;
}
medium
A. Mutating state directly instead of returning a new state
B. Missing default case in reducer
C. Incorrect action type string
D. Reducer should not return state

Solution

  1. Step 1: Check state mutation

    The reducer uses state.push(), which changes the original array directly.
  2. Step 2: Understand NgRx immutability rule

    Reducers must return new state objects without mutating the old state.
  3. Final Answer:

    Mutating state directly instead of returning a new state -> Option A
  4. Quick Check:

    Reducers must be pure and immutable [OK]
Hint: Never mutate state; always return new object/array [OK]
Common Mistakes:
  • Using push instead of spread operator
  • Ignoring immutability in reducers
5. You want to create a feature state slice for user profiles using NgRx. Which combination correctly sets up the feature state and selector?
1. Define interface UserProfileState { name: string; age: number; }
2. Create reducer userProfileReducer
3. Register feature state with key 'userProfile'
4. Select user name from store
Which code snippet correctly selects the user name?
hard
A. const selectUserProfile = createFeatureSelector<UserProfileState>('userProfile'); const selectUserName = createSelector(selectUserProfile, state => state.name);
B. const selectUserName = createSelector('userProfile', state => state.name);
C. const selectUserProfile = createSelector('userProfile'); const selectUserName = state => state.name;
D. const selectUserName = createFeatureSelector<UserProfileState>('userProfile').pipe(map(state => state.name));

Solution

  1. Step 1: Understand feature selector usage

    Use createFeatureSelector with the feature key to get the feature state.
  2. Step 2: Create selector for user name

    Use createSelector with the feature selector and a projector function to select the name.
  3. Final Answer:

    const selectUserProfile = createFeatureSelector<UserProfileState>('userProfile'); const selectUserName = createSelector(selectUserProfile, state => state.name); -> Option A
  4. Quick Check:

    Feature selector + createSelector = correct pattern [OK]
Hint: Use createFeatureSelector then createSelector for nested state [OK]
Common Mistakes:
  • Passing string directly to createSelector
  • Using pipe on selector instead of RxJS operators in component