Angular components are the building blocks of the UI: they pair a template with state, inputs, outputs, and style so a view can stand on its own.
Focus on the component boundary, standalone metadata, template wiring, and how inputs and outputs move data across components.
A strong understanding of components should include how the decorator config maps to runtime behavior and how change detection sees the view.
Angular Components Building Blocks should be studied as a practical Angular lesson, not as a label. Start by naming the input, the rule that changes the input, and the result a learner should be able to predict after reading the page.
In the angular > components page, the notes should connect the definition with a working scenario, a mistake that beginners actually make, and the exact check that proves the fix. That makes the topic useful for coding, debugging, and interview revision.
Components are one of the basic building blocks of any Angular application. In Angular 21, all new components are standalone by default - they do not require an NgModule. A component contains HTML to display a view, CSS to style it, and TypeScript to control it. A component is created using the @Component() decorator, which includes a standalone: true property by default and holds the following properties:-
If it set, the templateUrl and styleUrl are resolved relative to the angular component.
List of dependency injection providers scoped to this or current component's view.
It contains the inline template of the component's view.
It contains the external template URL of the component's view.
It contains the list of inline CSS styles for styling the component's view.
It contains the external stylesheet URLs for styling the component's view.
import { Component, signal } from '@angular/core';
@Component({
selector: 'app-root',
standalone: true,
template: `
<div style="text-align:center">
<h1>Welcome to {{ title() }}!</h1>
<p>Edit this component to get started.</p>
</div>
`,
styles: [`
h1 { color: green; }
`]
})
export class AppComponent {
title = signal('my-angular-app');
}
A Angular component/directive has a lifecycle that provide visibility into these key life moments and the ability to act when they occur. Once component/directive is getting created, Angular calls the constructor first, and then it calls the lifecycle hook methods in the following sequence.
| Hook | Purpose and Timing |
|---|---|
| ngOnChanges() | Called before ngOnInit() every time, as soon as a bound input property changes. |
| ngOnInit() | Called after ngOnChanges() once the angular component is initialized. |
| ngDoCheck() | Called immediately after ngOnChanges() and ngOnInit() during every change detection run. |
| ngAfterContentInit() | Called once after the first ngDoCheck() and as soon as an angular performs any content projection into the view. |
| ngAfterContentChecked() | Called every time after the ngAfterContentInit() and every subsequent ngDoCheck() as soon as the projected content has been checked. |
| ngAfterViewInit() | Called once after the first ngAfterContentChecked() and as soon as the component view and its child views has been initialized. |
| ngAfterViewChecked() | Called after the ngAfterViewInit() and every subsequent ngAfterContentChecked() and every time the component view and its child views have been checked. |
| ngOnDestroy() | Called once the component is about to destroyed. It unsubscribe Observables and detach event handlers to avoid memory leaks. |
import {
Component, OnInit, OnChanges, DoCheck,
AfterContentInit, AfterContentChecked,
AfterViewInit, AfterViewChecked, OnDestroy,
signal, input, SimpleChanges
} from '@angular/core';
@Component({
selector: 'app-lifecycle',
standalone: true,
template: `<p>Check the console for lifecycle hook output.</p>`
})
export class LifecycleComponent implements OnInit, OnChanges, DoCheck,
AfterContentInit, AfterContentChecked, AfterViewInit, AfterViewChecked, OnDestroy {
name = input('Angular');
ngOnChanges(changes: SimpleChanges) { console.log('ngOnChanges', changes); }
ngOnInit() { console.log('ngOnInit'); }
ngDoCheck() { console.log('ngDoCheck'); }
ngAfterContentInit() { console.log('ngAfterContentInit'); }
ngAfterContentChecked() { console.log('ngAfterContentChecked'); }
ngAfterViewInit() { console.log('ngAfterViewInit'); }
ngAfterViewChecked() { console.log('ngAfterViewChecked'); }
ngOnDestroy() { console.log('ngOnDestroy'); }
}
In Angular 21, all new components are standalone by default. Standalone components do not require an NgModule - they declare their own dependencies directly in the imports array of the @Component decorator. This simplifies the application structure significantly.
Angular 21 introduces signal-based component APIs as the modern way to define inputs, outputs, and two-way bindings:
import { Component, input, output } from '@angular/core';
@Component({
selector: 'app-greeting',
standalone: true,
template: `
<p>Hello, {{ name() }}!</p>
<button (click)="greet.emit(name())">Say Hi</button>
`
})
export class GreetingComponent {
name = input.required<string>(); // required signal input
greet = output<string>(); // signal output
}
import { Component } from '@angular/core';
import { GreetingComponent } from './greeting.component';
@Component({
selector: 'app-root',
standalone: true,
imports: [GreetingComponent],
template: `
<app-greeting
name="Angular 21"
(greet)="onGreet($event)"
/>
<p>{{ message }}</p>
`
})
export class AppComponent {
message = '';
onGreet(name: string) {
this.message = \`Greeted: \${name}\`;
}
}
Angular Components Building Blocks matters in Angular because it changes how a program is written, tested, or debugged. The page should explain the normal flow first: what the developer writes, what the runtime or platform does, and what result should appear.
When teaching Angular Components Building Blocks, avoid stopping at syntax. Show the surrounding decision: why this feature is chosen, what problem it removes, and what would become harder if the feature were not used.
The strongest notes for Angular Components Building Blocks explain where the idea stops working. Add cases for missing input, wrong order, incompatible types, duplicate values, empty collections, failed requests, or configuration mismatch when those cases fit the lesson.
Readers should leave the page knowing how to inspect a bad result. For Angular Components Building Blocks, that means checking the relevant value, state, dependency, selector, query, route, class, or runtime message before changing code randomly.
const state = { topic: "Angular Components Building Blocks", ready: true };
if (state.ready) {
console.log(state.topic + ": render or run the normal path");
}
const response = null;
const message = response?.message ?? "Angular Components Building Blocks: show a clear fallback";
console.log(message);
Memorizing Angular Components Building Blocks without the situation where it is useful.
Connect Angular Components Building Blocks to a concrete Angular task.
Testing Angular Components Building Blocks only with the perfect input.
Include empty, missing, duplicate, incompatible, or failed cases when relevant.
Changing code before reading the visible symptom or error message.
Inspect the output, state, configuration, or stack trace connected to Angular Components Building Blocks.
Memorizing Angular Components Building Blocks without the situation where it is useful.
Connect Angular Components Building Blocks to a concrete Angular task.
A component is a directive with a template - it creates a new HTML element. A directive modifies existing elements without creating new ones. Components use @Component; directives use @Directive.
Standalone components (default in Angular 17+) do not belong to any NgModule. They declare their own imports directly in the @Component decorator. This simplifies the architecture and enables better tree-shaking.
Use a shared service with a signal or BehaviorSubject. Parent-to-child: @Input(). Child-to-parent: @Output() EventEmitter. Sibling-to-sibling: shared service or state management (NgRx, Signals).
ViewEncapsulation controls how component styles are scoped. Emulated (default): styles are scoped to the component via attribute selectors. None: styles are global. ShadowDom: uses native Shadow DOM for true encapsulation.
Explore 500+ free tutorials across 20+ languages and frameworks.