Featured resource
Tech Upskilling Playbook 2025
Tech Upskilling Playbook

Build future-ready tech teams and hit key business milestones with seven proven plays from industry leaders.

Learn more
  • Labs icon Lab
  • Core Tech
Labs

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.

Labs

Path Info

Level
Clock icon Intermediate
Duration
Clock icon 45m
Last updated
Clock icon Aug 07, 2025

Contact sales

By filling out this form and clicking submit, you acknowledge our privacy policy.

Table of Contents

  1. 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:

    1. src/app/app.config.ts: Main application configuration with store setup
    2. src/app/components/todo-list/todo-list.component.ts: Displays the list of todos
    3. src/app/components/add-todo/add-todo.component.ts: Form for adding new todos
    4. src/app/models/todo.model.ts: TypeScript interface for todo items
    5. src/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.

  2. 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 the createAction 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.

  3. 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 the on() 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 and createSelector, 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.

  4. 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, and exhaustMap for preventing duplicate requests.

    For this lab, we'll simulate an API call using of() and delay() to demonstrate the pattern without requiring a backend.

  5. 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.

  6. 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.

  7. 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:

    1. Created the State Foundation: Built a type-safe model and defined actions for state changes.
    2. Built the State Layer: Implemented reducers, configured the store, and created efficient selectors.
    3. Handled Side Effects: Used effects to manage asynchronous operations properly.
    4. Connected Components: Integrated UI components with the centralized store.
    5. 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:

    1. Initial Load: The app shows "Loading todos..." then display the todo list
    2. Add Todo: New todos appear immediately in the list
    3. 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.

Angel Sayani is a Certified Artificial Intelligence Expert®, CEO of IntellChromatics, author of two books in cybersecurity and IT certifications, world record holder, and a well-known cybersecurity and digital forensics expert.

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.