Bird
Raised Fist0
Angularframework~20 mins

NgRx store concept in Angular - Practice Problems & Coding Challenges

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
Challenge - 5 Problems
🎖️
NgRx Mastery
Get all challenges correct to earn this badge!
Test your skills under time pressure!
component_behavior
intermediate
2:00remaining
What is the output of this Angular component using NgRx store?

Consider this Angular component that selects a piece of state from the NgRx store and displays it.

import { Component } from '@angular/core';
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs';

@Component({
  selector: 'app-counter',
  template: `
Count: {{ count$ | async }}
` }) export class CounterComponent { count$: Observable; constructor(private store: Store<{ count: number }>) { this.count$ = this.store.select('count'); } }

If the store's state is { count: 5 }, what will this component render?

ACount: 5
BCount: NaN
CCount: 0
DCount: undefined
Attempts:
2 left
💡 Hint

Think about what the select method does and how the async pipe works.

state_output
intermediate
2:00remaining
What is the new state after this NgRx reducer runs?

Given this reducer function for a counter feature:

import { createReducer, on } from '@ngrx/store';
import { increment, decrement } from './counter.actions';

export const initialState = 0;

export const counterReducer = createReducer(
  initialState,
  on(increment, state => state + 1),
  on(decrement, state => state - 1)
);

If the current state is 3 and the increment action is dispatched, what will be the new state?

A4
B3
C-1
D0
Attempts:
2 left
💡 Hint

Look at how the reducer updates the state when the increment action is received.

📝 Syntax
advanced
2:00remaining
Which option correctly defines an NgRx action with a payload?

Which of the following code snippets correctly defines an NgRx action named addItem that carries a payload of type string?

A
import { createAction } from '@ngrx/store';
export const addItem = createAction('addItem', (payload: string));
B
import { createAction } from '@ngrx/store';
export const addItem = createAction('addItem', { item: string });
C
import { createAction, props } from '@ngrx/store';
export const addItem = createAction('addItem', (item: string) =&gt; ({ item }));
D
import { createAction, props } from '@ngrx/store';
export const addItem = createAction('addItem', props&lt;{ item: string }&gt;());
Attempts:
2 left
💡 Hint

Remember that NgRx actions with payloads use props to define the payload shape.

🔧 Debug
advanced
2:00remaining
Why does this NgRx selector cause a runtime error?

Given this selector code:

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

const selectFeature = (state: any) => state.feature;

const selectItems = createSelector(
  selectFeature,
  (feature) => feature.items
);

When the store state is {} (empty object), selecting selectItems causes an error. Why?

ABecause the selector must return an observable, not a value.
BBecause <code>createSelector</code> requires three arguments, not two.
CBecause <code>feature</code> is undefined, accessing <code>feature.items</code> throws a TypeError.
DBecause the state parameter must be typed as <code>any</code> to avoid errors.
Attempts:
2 left
💡 Hint

Think about what happens if state.feature does not exist.

🧠 Conceptual
expert
2:00remaining
What is the main benefit of using NgRx store in Angular applications?

Choose the best explanation for why developers use NgRx store in Angular apps.

AIt replaces Angular's dependency injection system for services.
BIt centralizes application state in a single immutable store, making state changes predictable and easier to debug.
CIt automatically generates UI components based on the state shape.
DIt allows direct manipulation of the DOM without Angular templates.
Attempts:
2 left
💡 Hint

Think about how NgRx helps manage state and debugging.

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