skip to content
BKB
Table of Contents

In this lesson we will make Angular display changing data and create our first reusable child component.

The idea

An Angular component usually has three parts:

  • a TypeScript class containing state and behavior;
  • an HTML template describing what the user sees; and
  • optional CSS scoped to that component.

Modern Angular components are standalone, which means they declare their own template dependencies instead of belonging to an NgModule.

1. Add a signal

A signal stores a value and tells Angular when that value changes.

In src/app/app.ts:

import { Component, signal } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.html',
styleUrl: './app.css'
})
export class App {
protected readonly title = signal('Angular Topic Viewer');
renameApp(): void {
this.title.set('Angular Knowledge Reloaded');
}
}

In src/app/app.html:

<h1>{{ title() }}</h1>
<button type="button" (click)="renameApp()">Rename application</button>
  • {{ title() }} is interpolation: it prints a value.
  • (click) is event binding: it runs code when an event occurs.
  • .set() replaces the signal’s current value.
Why do we write title() instead of title?

A signal is read by calling it like a function. This also lets Angular track which template used the value.

2. Generate a child component

Terminal window
ng generate component welcome-card

In welcome-card.ts, add an input and output:

import { Component, input, output } from '@angular/core';
@Component({
selector: 'app-welcome-card',
templateUrl: './welcome-card.html',
styleUrl: './welcome-card.css'
})
export class WelcomeCard {
readonly heading = input.required<string>();
readonly dismissed = output<void>();
dismiss(): void {
this.dismissed.emit();
}
}
<section>
<h2>{{ heading() }}</h2>
<p>This content belongs to the child component.</p>
<button type="button" (click)="dismiss()">Dismiss</button>
</section>

An input sends data from parent to child. An output sends an event from child to parent.

Import WelcomeCard in the root component, add a visibility signal, and render it:

@if (showWelcomeCard()) {
<app-welcome-card
[heading]="title()"
(dismissed)="hideWelcomeCard()"
/>
}

Checkpoint

  • The page shows the signal value.
  • Rename changes the heading without reloading.
  • The child displays the parent’s title.
  • Dismiss asks the parent to hide the child.

Small challenge

Add a second input named message and display it below the heading.

Navigation: Series overview · Next: Routing