Featured resource
2026 Tech Forecast
2026 Tech Forecast

Stay ahead of what’s next in tech with predictions from 1,500+ business leaders, insiders, and Pluralsight Authors.

Get these insights
  • Lab
    • Libraries: If you want this lab, consider one of these libraries.
    • Core Tech
Labs

Guided: Angular Foundations

Imagine you've just joined a development team maintaining an e-commerce website that sells robot parts. The site is functional, but it lacks key functionality and features. Your mission? To dive into the codebase and make strategic improvements to enhance the user experience—all while mastering essential Angular concepts. In this hands-on lab, you’ll work with a pre-existing application consisting of a catalog page and cart page. Along the way, you'll practice creating new components, adding routing and app routes, linking to components/pages, repeating data with for loops, passing data to components with input properties, and creating and consuming services. Each step will guide you through modifying the application, reinforcing Angular fundamentals in a practical, real-world scenario. By the end of the lab, you won’t just understand Angular—you’ll have applied it, gaining the necessary skills to start building your own dynamic web applications! Your robot parts store awaits its transformation—are you ready to take it to the next level?

Lab platform
Lab Info
Level
Beginner
Last updated
Oct 27, 2025
Duration
47m

Contact sales

By clicking submit, you agree to our Privacy Policy and Terms of Use.
Table of Contents
  1. Challenge

    Introduction

    In this Angular guided lab, you'll be working with the Joe's Robot Shop application. The app is currently functional but missing key features.

    To see its current rudimentary state:

    1. Click the Run button in the Terminal tab in the bottom-right.
    2. Then, click either the Web Browser tab to the right, or click on this link to open the app in a new browser tab: {{localhost:4200}}.

    You'll notice that it currently displays a simple Catalog page with only one hard-coded product. There's currently no way to display multiple products, add items to a cart, or navigate to a Cart page.


    What You'll Work On:

    In this lab, you'll implement various features including:

    • Adding and navigating to routes
    • Using the Angular CLI to generate components
    • Passing data to child components
    • Repeating elements with @for
    • Creating and injecting services
    • Managing cart state with Angular state management

    Solution Directory and Validation

    As you work through each step, tasks can be validated by clicking on the Validate button. If you're stuck or would like to compare solutions, a /solution folder has been provided for you.


    Before You Get Started

    If you haven't already, click the Run button in the Terminal tab, then go ahead and continue to the next step.

  2. Challenge

    Add Routing to Your App

    You are starting with a working Angular application, but the app currently has no routing.

    Notice that the App component template (src/app/app.html) has the <bot-catalog /> component hard-coded in its HTML. As it stands, to display a different component, you'd have to manually edit the App component template.

    To add routing so pages load dynamically based on the URL:

    1. Define routes for the Catalog and Cart pages in a new app.routes.ts file.
    2. Then, provide those routes in the app.config.ts file using provideRouter().
    3. Update the App component template (src/app/app.html) to use the <router-outlet /> component to render routed content.

    Reminder

    You define routes as an array of route objects like this:

    import { Routes } from '@angular/router'; 
    
    export const routes: Routes = [
      { path: 'page-one', component: PageOne },
      { path: 'page-two', component: PageTwo },
    ];
    

    Then, you provide a route configuration for your application in app.config.ts by calling provideRouter() (also imported from @angular/router)and passing your routes as a parameter.

    Checkpoint

    Great, you now have routes and can technically navigate to them in the browser, but the app will still only display the Catalog page.

    Feel free to verify this:

    • Open the Web Browser tab,
    • Navigate to the Catalog ([baseUrl]/catalog) and Cart ([baseUrl]/cart) pages
    • Notice that the URL changes, but the app still shows the Catalog page every time

    This is because the App component is hard coded to render the Catalog component.

    Update the App component's template (src/app/app.html) to render the <router-outlet /> component instead. This ensures the App component always displays the content that corresponds to the current route/URL.

    Final Check for Step 2

    Great! You can now navigate to the Catalog and Cart pages. Check it out:

    • Open the Web Browser tab, or at {{localhost:4200}}
    • Navigate to the Catalog ([baseUrl]/cart) and Cart ([baseUrl]/cart) pages
    • Confirm that the URL changes and the correct page content is rendered for each route
  3. Challenge

    Create a New Component with Navigation

    You can now navigate to the Catalog and Cart pages by changing the URL, but you can't yet navigate to them by clicking on links.

    You could add links directly to the App component, but instead add a new SiteHeader component to get some practice creating new components. You'll add links to this new component in a later step.

    Use the Angular CLI to generate a new component named SiteHeader.

    info> Reminder: You can generate new components with the CLI using the command: ng generate component [ComponentName] or the abbreviated command: ng g c [ComponentName]

    warning> Important: Because of the unique lab environment you're working in, you must prefix Angular CLI commands with ng commands with npx. For example: npx ng generate component [ComponentName] Great! You've created the SiteHeader component, now make it so that the SiteHeader component shows above every routed page.

    Remember, routed pages are rendered inside the <router-outlet/> component you added to the App component template (src/app/app.html).

    If you want the content to render above every routed page, you can just add it to the App component's template above the <router-outlet />. Nice! You should now see a Joe's Robot Shop Logo at the top left of every page in the Web Browser.

    It's a little big though and you're going to be adding more items to the SiteHeader that need to be laid out correctly, so now is a good time to add some CSS styles to your SiteHeader component stylesheet. Now that your site header is rendering and styled, add navigation links for the Catalog and Cart pages. These links should appear after the logo.

    To add a link to an Angular route, use an anchor tag (<a>) and use the routerLink directive to specify the path.

    For example, the following would navigate to the page1 route:

    <a routerLink="/page1">Page One</a>
    

    info> Remember: To use the routerLink directive, you need to be sure to import the RouterLink directive in your SiteHeader component's imports array.

  4. Challenge

    Pass Data to Child Components with Inputs

    The Catalog page is currently displaying only a single product, and the data for that product is hard-coded.

    Take a look at the product-details component class: src/app/product-details/product-details.ts

    Notice that it has a product property, and that property is initialized in the constructor to a hard-coded "Friendly Bot" product. This means this ProductDetails component can't be reused to render different products.

    A better approach is to make the ProductDetails component receive the product to display as an input property. Since the component cannot function without a product, this input should be required. Use a signal-based required input property for this.

    info> Remember: You can create a required signal-based input property using the following syntax: myProperty = input.required<IMyPropertyType>(); Because you changed the product property on the ProductDetails component from a standard object to a signal-based input property, you need to update the ProductDetails template.

    Signal values are accessed like function calls, so anywhere the template references the product fields, update them to use product(), for example: product().name. Your ProductDetails component can now receive a product as an input. In fact it is required. Because of this, the Catalog page will no longer render.

    If you open the app in the Web Browser in a separate tab using {{localhost:4200}}), you can then open the Chrome DevTools and see that you're getting an error that says something like:

    "Input "product" is required but no value is available yet."

    This is because the Catalog component is not yet passing a value into the now-required product input on the ProductDetails component.

    Currently, the Catalog component renders a single ProductDetails component. Later, you'll fetch product data from an API and use a loop to render multiple products. For now, to get your app rendering again and demonstrate passing data into the new input, update the Catalog component to pass a hard-coded product object into the ProductDetails component.


    How to Pass Data to an Input Property

    You pass data to an input property using an input property attribute binding on the child component.

    For example, to pass the value in myObject to the myProperty input property on a child component, you do something like this in the parent component:

    <my-child-component [myProperty]="myObject" />
    
  5. Challenge

    Create and Use Services for State Management

    Currently, our Catalog component is only displaying a single product. In this step, you'll update the Catalog component to fetch a list of products from the existing ProductsService.

    Open src/app/products-service.ts. Notice this service uses an HttpResource to fetch an array of products from the API at /api/products. This project is using Angular's In-memory Web API to serve up an API without running a separate API server.

    You can see the array of products that is being returned from /api/products in the file in-memory-products.service.ts. Notice that this is an array of product objects which each have properties such as id, name, and others. When the ProductsService makes an HTTP call to /api/products, this is the data that will be returned.

    The service also exposes a products computed signal property. This signal contains the array of products returned from the API.

    Update the Catalog component class so that it:

    • Injects the ProductsService
    • Uses a @for loop in the Catalog component's template to loop over the array of products from the product property of the injected ProductsService

    Reminder: Injecting a Service

    To inject a service use the inject function.

    For example:

    protected myService = inject(MyService)
    

    Reminder: Using @for In a Template

    You use a @for loop in a component template to loop over an array and render elements for each item in the array.

    The basic syntax for a @for loop looks like this:

    @for (item of itemsArray; track item.id) {
      <my-child-component [itemProperty]="item" />
    }
    ``` You’ve now practiced using an existing service, so next you’ll create your own. In this step, you’ll build a `CartService` to store and manage the items in the user’s cart.
    
    You’ll create the service using the Angular CLI, then add:
    - A signal-based `cart` property that stores an array of `IProduct` objects
    - A method to add items to the cart
    - A method to remove items from the cart
    
    ---
    
    ### Reminders
    - Create a service with: `npx ng generate service CartService`
    - Create a signal with a default value like:
        ```ts
        myName = signal<string>('Jim')
        ```
    - Access a signal’s value by calling it like a function:
        ```ts
        myName()
        ```
    - New services generated with the CLI are automatically decorated with `@Injectable({ providedIn: 'root' })` The cart should contain the logic for adding and removing items to/from the cart. Add two methods, `addToCart()` and `removeFromCart()`, to handle these operations.
    
    **Remember:** When you want to update a signal's value based on it's previous value (for example, adding items to the existing array), use the signal's `update` method. 
    
    Example: 
    
    ```ts
    myArraySignal.update((a) => [...a, newItem])
    

    Now, inject and use your new service on the product-details component to add items to the cart from the catalog page and display those items on the cart page. Nice! You can now add items to your cart from the Catalog page, but you still can’t see those items on the Cart page.

    The Cart component is used to display the Cart page and is currently using a hard-coded cartItems property to show a single hard-coded product.

    Your next steps will wire the Cart page into your new CartService:

    • Update the Cart component to get its array of cart items from your new CartService instead of using the hard-coded cartItems.
    • Then, update the CartItem component, which has the Remove from cart button so that it removes the associated item from the cart via the CartService when clicked.

    What You Learned

    Congratulations, you've finished this lab and now have a functioning Robot Shop!

    Throughout this lab you:

    • Added routing and custom routes for your pages
    • Created a new component with navigation links for each of your pages
    • Styled your new component
    • Used a @for loop to repeat elements on the catalog page
    • Created, injected, and used services to manage the state of your application

    Keep Learning

    Check out the Pluralsight Angular: Components and Templates course and its associated lab to keep learning!

About the author

Jim Cooper is a software developer at Pluralsight. With more than 20 years of software development experience, he has gained a passion for Agile software development -- especially Lean.

Real skill practice before real-world application

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.

Learn by doing

Engage hands-on with the tools and technologies you’re learning. You pick the skill, we provide the credentials and environment.

Follow your guide

All labs have detailed instructions and objectives, guiding you through the learning process and ensuring you understand every step.

Turn time into mastery

On average, you retain 75% more of your learning if you take time to practice. Hands-on labs set you up for success to make those skills stick.

Get started with Pluralsight