How To Pass Data To Angular Child Components

In this post, we will show how to pass data down to a child component in Angular. To do this, we will start by creating a new Angular app using CLI. We then create an initial example in AppComponent and eventually, we will move the example into a child component.

If you want to learn more about Angular CLI, have a look at the official documentation.

Creating A New Angular App

First of all, we create a new Angular app using the CLI command ng new bindingDown, where bindingDown is the name of our new Angular app.
We should then answer a few questions:

  • Do you want to enforce stricter type-checking and stricter bundle budgets in the workspace? This setting helps improve maintainability and catch bugs ahead of time. For more information, see https://angular.io/strict (y/N) N
  • Would you like to add Angular routing? N
  • Which stylesheet format would you like to use? CSS
Angular CLI questions
Answer Angular CLI questions to create a new Angular App

Once the CLI finished installing all the packages, you are ready to run your Angular application. Move into bindingDown and use the CLI command ng serve --open. Your code gets compiled and Angular Live Development Server gets started. Once everything is done, you should see a new tab opening in your browser.

Default Angular Application landing page
Default Angular Application

Code Without Child Component

The initial folder structure of this Angular application looks like this:

Initial Angular app setup to pass data to child components
Angular folder structure

In this Angular application, bindingDown is the root folder.

Navigate to src/app/ to see AppComponent. As in most Angular components, AppComponent has four relevant files:

  • app.component.html (template)
  • app.component.ts (class)
  • app.component.css (style)
  • app.component.spec.ts (testing)

In app.component.html you can see the HTML code that is creating the initial Angular page in your browser.

At the moment, AppComponent is the default and only component in our application. To start, we delete the code in the app template (app.component.html). Once you are done with this, you will have a blank page in your browser.

Initial code

Let’s write some simple code to have a basic application:

app.component.html

<h1>This is {{title}}</h1>
<div>
  <h2>My favorite books</h2>
  <ul>
    <li *ngFor="let book of favBooks" >
      {{book.title}}
    </li>
  </ul>
</div>

app.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  title = 'bindingDown';
  favBooks = [
    { title: 'Principles' },
    { title: 'The Story of Success' },
    { title: 'Extreme Economies' },
  ];
}

The template (app.component.html) gets the values of title and favBooks from app.component.ts. Since all the code is in the same component (AppComponent) everything works just fine.

Initial Angular app
The initial app displays a list of books

However, as your Angular app grows more complex you may want to split your code into several components.

Following, we will create a new component, ListFavorites, and we will move the HTML code that shows the list of books to the child component, ListFavorites. The array favBooks will remain in app.component.ts so we will pass the value of the array from AppComponent down to ListFavorites.

Consequently, we will need to pass a custom Angular property from a parent component to a child component.

Generating new Angular Components

Generating new Angular Components is pretty straightforward using the Angular CLI. Run ng g c list-favorites from the root folder to generate a new component called ListFavorites. ListFavorites has the same structure as any Angular component:

ListFavorites Angular component file structure
ListFavorites structure

After we have ListFavorites, we change our code as follows:

app.component.html

<h1>This is {{title}}</h1>
<h2>My favorite books</h2>
  <ul>
    <app-list-favorites 
      *ngFor="let book of favBooks"
    >
    </app-list-favorites>
  </ul>

list-favorites.component.html

<li>
  {{book.title}} 
</li>

and our app crashes.

What’s going on here?

To understand what is happening here, we go through three steps:

  1. We moved some code into list-favorites.component.html. This component has a selector (that you can see in list-favorites.component.ts) called app-list-favorites.
  2. We use the app-list-favorites selector as a tag in app.component.html to refer to the code inside list-favorites.component.html.
  3. Once list-favorites.component.html is used inside app.component.html, it tries to get the value of favBooks. However, favBooks is declared in app.component.ts but list-favorites.component.html looks for that property inside list-favorites.component.ts and not in app.component.ts. As a consequence, we get an error: Property ‘favBooks’ does not exist on type ‘ListFavoritesComponent’.

How To Pass Data To A Child Component In Angular

There are three key steps to pass data (properties) to a child component in Angular.

1. Prepare Child Component class for external Input

Prepare the child component class (list-favorites.component.ts) to receive external inputs.

  • External refers to data that is not available inside the component itself,
  • Input refers to the property that the parent component passes to the child component.

The input is the property that AppComponent passes to ListFavorites. In our case, we name the input bookObject.

// list-favorites.component.ts

...
export class ListFavoritesComponent implements OnInit {
  @Input() bookObject: { title: string };
  constructor() {}

  ngOnInit(): void {}
}

The @Input() decorator expects a property that we named bookObject of type object with a key named title of type string.

2. Bind Property in Parent component template – Angular’s way to pass data

First of all, we need to remember that we have some data in app.component.ts, specifically favBooks. We want to pass favBooks from the parent component (AppComponent) to the child component (ListFavorites).

To do so, we need to bind the data coming from the parent component class (app.component.ts) to the custom property, bookObject, that we declared in the child component class (list-favorites.component.ts).

Quick recap:

  • Data in app.component.ts: favBooks
  • Custom property in list-favorites.component.ts: bookObject
  • Property binding syntax: [property]=”data”

The binding happens in app.component.html which becomes the point of contact between app.component.ts and list-favorites.component.ts

Using *ngFor, for each item in favBooks we pass a book property to a different instance of app-list-favorites.
We bind the book element (one of the items in favBooks) to our custom bookObject property in list-favorites.component.ts using property binding: [bookObject] = "book".

// app.component.html 

...
  <ul>
    <app-list-favorites 
      *ngFor="let book of favBooks"
      [bookObject] = "book"
      >
    </app-list-favorites>
  </ul>

Consequently, ListFavorites expects a property from AppComponent. The binding happens in app.component.html and the value of the property becomes available inside ListFavorites.

3. Use Property in Child Component template

We can finally use the bookObject property inside our child component template. As a result, we can use this Angular custom property in the child component.

// list-favorites.component.html

<li>
  {{bookObject.title}} 
</li>

Conclusions

The app is now working and it is possible to pass data (properties) from a parent component (AppComponent) to a child component ListFavorites) in Angular. At first glance, it seems nothing changed.

This is normal because from a visual point of view, nothing should change. If you want to verify the difference, open the developer tool in your browser and inspect the code.

Developer Tools shows how Angular passes data to child components
Single component app
Developer Tools shows how Angular passes data to child components
AppComponent calls ListFavorites

In conclusion, using a theoretical approach where AppComponent is the Parent component and ListFavorites is the Child component, remember the three steps:

  1. Prepare Child.ts for external Input
  2. Bind Property in Parent.html
  3. Use Property in Child.html

At this point, you may want to pass data the other way around e.g. from Child to Parent. If you want to know more about this, have a look at Passing Data from Child to Parent component in Angular.

Next: Introduction To Angular Services