- Lab
- Core Tech

Guided: Managing State with NgRx Essentials in Angular
Transform your Angular application's state management by implementing NgRx in a practical todo application. Through CLI automation and minimal configuration, you'll build a complete state management flow including actions, reducers, selectors, and effects. Learn to connect standalone components to the store, handle asynchronous operations, and maintain predictable state updates. This hands-on lab demonstrates real-world patterns you can immediately apply to your projects.

Path Info
Table of Contents
-
Challenge
Introduction
Introduction
Welcome to the NgRx Essentials Code Lab! In this lab, you'll transform a basic todo application by implementing professional-grade state management using NgRx. You'll learn to manage application state predictably, handle asynchronous operations, and connect UI components to a centralized store using modern standalone components.
Background
Globomantics has been experiencing growing pains with their task management system. As their development teams have expanded from 5 to 50 members, managing shared application state through services and component communication has become increasingly complex. Tasks get out of sync, updates are lost, and debugging state-related issues consumes valuable development time.
As a front-end developer on the platform team, you've been tasked with implementing NgRx to create a single source of truth for application state. Your implementation will establish patterns that other teams can follow. This will improve code maintainability and reducing state-related bugs across the entire platform.
Explore the Program Structure
The project is structured using Angular CLI and standalone components. The key files include:
src/app/app.config.ts
: Main application configuration with store setupsrc/app/components/todo-list/todo-list.component.ts
: Displays the list of todossrc/app/components/add-todo/add-todo.component.ts
: Form for adding new todossrc/app/models/todo.model.ts
: TypeScript interface for todo itemssrc/app/state/
Directory where all NgRx files will be generated
The application uses Angular CLI's development server. You can run the application using
npx ng serve --host 0.0.0.0 --disable-host-check
in the terminal.Terminal Tip: The development server runs continuously and auto-refreshes when you save files. To stop the server and regain terminal control (for example, to run tests in Task 11), press
Ctrl+C
. You can then restart the server with the same command.Navigate to
http://localhost:4200
in your Web Browser to see the running application.Note Before You Start
All NgRx packages have been pre-installed for you. The application in the Web Browser will compile and display immediately with placeholder content. You'll see the Globomantics Task Manager title and disabled components with helpful messages.
As you complete each task, the application will progressively gain state management capabilities.
warning> Important: Complete each task sequentially, as later tasks depend on earlier ones. Refresh your browser after completing each task to see the changes take effect.
info> Use Validation Feedback: When you're ready, dive into the coding process. Use the validation feedback in the Feedback/Checks section to guide you if you encounter any problems.
-
Challenge
Creating the State Foundation
Introduction to NgRx
NgRx is Angular's implementation of the Redux pattern, providing a predictable state container for your applications. It ensures that state mutations happen in a controlled manner through actions and reducers, making your application more maintainable and easier to debug.
The core concepts you'll work with are:
| Concept | Description | |-----------|-----------------------------------------------------------------------------| |
Store
| The single source of truth containing all application state | |Actions
| Plain objects describing what happened in the application | |Reducers
| Pure functions that specify how state changes in response to actions | |Selectors
| Functions that derive and transform data from the store | |Effects
| Handle side effects like API calls and asynchronous operations |Understanding these concepts is crucial because NgRx fundamentally changes how data flows through your application. Instead of scattered state in components and services, you'll have a centralized, predictable state management system.
Now that you've seen the core concepts of NgRx, you're ready to implement state management in the Globomantics todo application. ## Understanding Actions and Action Creators
Actions are the only way to trigger state changes in NgRx. Each action is a plain object with a
type
property that describes what happened. Modern NgRx uses action creator functions generated by thecreateAction
function, which provide type safety and reduce boilerplate.Actions should be thought of as events, not commands. Name them to describe what happened, not what should happen. For example, use
'[Todo] Add Todo'
instead of'[Todo] Save Todo to State'
.The
props
function allows you to define the payload that actions carry. This ensures type safety when dispatching actions and handling them in reducers. -
Challenge
Building the State Layer
Working with Reducers
Reducers are pure functions that take the current state and an action, then return a new state. They must be predictable: given the same inputs, they always produce the same output. This predictability makes your application easier to test and debug.
NgRx provides the
createReducer
function to reduce boilerplate. You define the initial state and use theon()
function to handle specific actions. Each handler returns a new state object, never mutating the existing one.Always use the spread operator or immutable update patterns to ensure you're creating new state objects rather than mutating existing ones. ## Understanding Selectors
Selectors are pure functions that derive data from the store. They act as queries to your state, allowing components to subscribe to specific pieces of data. Selectors are memoized, meaning they only recalculate when their inputs change, improving performance.
Using
createFeatureSelector
andcreateSelector
, you can compose complex queries from simple ones. This composability makes it easy to derive exactly the data your components need without duplicating logic.Well-designed selectors create a clean API between your store and components, hiding the internal structure of your state.
-
Challenge
Handling Side Effects
Implementing Effects for Side Effects
Effects handle operations that interact with the outside world, like API calls. They listen for actions, perform side effects, and dispatch new actions with the results. This keeps your reducers pure while still allowing complex asynchronous workflows.
Effects use RxJS operators to transform action streams. Common patterns include using
switchMap
for cancellable requests,mergeMap
for parallel requests, andexhaustMap
for preventing duplicate requests.For this lab, we'll simulate an API call using
of()
anddelay()
to demonstrate the pattern without requiring a backend. -
Challenge
Connecting Components to Store
Connect and Display Store Data
Time to connect your first component to the store and see real data! ## Dispatching Actions from Components
Components interact with the store by dispatching actions. This creates a unidirectional data flow: actions trigger reducers, which update the state; selectors then retrieve the updated data for the component to render.
When dispatching actions with payloads, ensure you're passing the correct data structure. TypeScript will help catch errors at compile time if you've defined your actions properly.
Remember that dispatching an action doesn't immediately update the state — it triggers a reducer that returns new state, which then flows back to components through selectors.
-
Challenge
Enhancing User Experience
Enhancing User Experience
You've built a functioning todo application with NgRx state management! The core functionality is in place — you can load and add todos.
However, professional applications need more than just basic functionality. They need to provide clear feedback to users and be thoroughly tested.
In this final section, you'll enhance the user experience by:
- Adding loading indicators to show when data is being fetched
- Providing visual feedback during asynchronous operations
- Writing comprehensive tests to ensure your state management logic is bulletproof
These enhancements transform a functional app into a polished, production-ready application that users will enjoy using. ## Displaying State in Templates
Angular's async pipe automatically subscribes to observables and unsubscribes when the component is destroyed. This prevents memory leaks and keeps your component code clean.
When working with multiple observables in a template, you can use the
async
pipe multiple times or combine selectors to create a view model. For loading states, conditional rendering with*ngIf
provides good user feedback.Always handle both loading and loaded states in your templates to create a smooth user experience. ## Testing State Management
Testing NgRx applications involves verifying that actions trigger the correct state changes and effects produce the expected actions. Unit tests for reducers are straightforward since they're pure functions.
For selectors, test that they correctly derive data from various state shapes. Effect tests verify that the right actions are dispatched in response to triggers.
Integration tests can verify the entire flow from user interaction through state changes to UI updates.
-
Challenge
CONCLUSION
Conclusion
Congratulations on completing the NgRx Essentials lab!
You've successfully implemented a robust state management solution that transforms how your Angular application handles data.
What You've Accomplished
Throughout this lab, you have:
- Created the State Foundation: Built a type-safe model and defined actions for state changes.
- Built the State Layer: Implemented reducers, configured the store, and created efficient selectors.
- Handled Side Effects: Used effects to manage asynchronous operations properly.
- Connected Components: Integrated UI components with the centralized store.
- Enhanced User Experience: Added loading states and comprehensive tests.
Key Takeaways
Here’s what you’ve learned:
- Unidirectional Data Flow: Actions flow in one direction, which makes state changes predictable.
- Immutability is Essential: Always return new state objects, never mutate existing ones.
- Effects Handle Complexity: Keep reducers pure by moving side effects to effects.
- Selectors Optimize Performance: Memoized selectors prevent unnecessary recalculations.
Testing Your Complete Application
Before finishing, verify that your implementation works correctly:
- Initial Load: The app shows "Loading todos..." then display the todo list
- Add Todo: New todos appear immediately in the list
- Action Replay: Use time-travel debugging to replay state changes
Extending Your Skills
To continue improving your NgRx expertise, consider exploring:
- Entity adapter for normalized state management
- Router store for syncing route state
- Component store for local component state
- Advanced effect patterns like polling and cancellation
- Facade services for simplified store access
Remember that NgRx is powerful but you should use it judiciously. Not every piece of state needs to be in the store. Use the store for state that's shared across components, needs to persist, or benefits from time-travel debugging.
The patterns you've learned here provide a solid foundation for building scalable Angular applications with predictable state management.
What's a lab?
Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.
Provided environment for hands-on practice
We will provide the credentials and environment necessary for you to practice right within your browser.
Guided walkthrough
Follow along with the author’s guided walkthrough and build something new in your provided environment!
Did you know?
On average, you retain 75% more of your learning if you get time for practice.