Components
Components are the building blocks of every Angular screen. Each one is a class with a template and styles — small, focused and reusable.
On this page · 5 min · Beginner
On this page
- Learning objectives
- Explanation
- Syntax
- Code example
- Step by step
- Real-world use
- Common mistakes
- Best practices
- Remember this
- Practice exercise
- Mini quiz
- Related topics
- My notes
- Reading time
- 5 min
- Difficulty
- Beginner
- Updated
- Oct 28, 2026
Learning objectives#
- Write a standalone component with @Component
- Use separate template and style files or inline ones
- Accept data with input()
- Compose components and understand style encapsulation
Explanation#
@Component({ selector, template or templateUrl, styles or styleUrl, imports }) turns a class into a component. The selector is the custom HTML tag: <app-product-card>.
Small components can use inline template and styles; larger ones use separate .html and .css files (the CLI default).
input() declares data passed in from the parent: name = input.required<string>(); price = input(0). Inside the template read them like signals: {{ name() }}.
A parent uses a child by importing the class in its imports array and writing its tag: <app-product-card [name]="p.name" />.
Styles are encapsulated by default: CSS in a component affects only that component’s template, so class names never clash.
Syntax#
@Component({
selector: 'app-product-card',
templateUrl: './product-card.html',
styleUrl: './product-card.css',
})
export class ProductCard {
name = input.required<string>();
price = input(0);
}
Code example: A reusable card used three times#
import { Component, input } from '@angular/core';
@Component({
selector: 'app-product-card',
template: `
<article class="card">
<h3>{{ name() }}</h3>
<p>₹{{ price() }}</p>
@if (price() > 500) { <span class="badge">Premium</span> }
</article>
`,
styles: `
.card { border: 1px solid #ddd; border-radius: 8px; padding: 12px; width: 160px; }
.badge { background: #fde68a; padding: 2px 6px; border-radius: 4px; }
`,
})
export class ProductCard {
name = input.required<string>();
price = input(0);
}
@Component({
selector: 'app-product-list',
imports: [ProductCard],
template: `
<section class="grid">
@for (p of products; track p.id) {
<app-product-card [name]="p.name" [price]="p.price" />
}
</section>
`,
styles: `.grid { display: flex; gap: 12px; }`,
})
export class ProductList {
products = [
{ id: 1, name: 'Pen', price: 20 },
{ id: 2, name: 'Notebook', price: 60 },
{ id: 3, name: 'Backpack', price: 1200 },
];
}
Three bordered cards appear in a row: “Pen ₹20”, “Notebook ₹60” and “Backpack ₹1200” with a yellow “Premium” badge. The .card styles apply only inside ProductCard.
This example is illustrative. Copy or download it and run it in your own environment; the expected output is shown above.
Step-by-step explanation#
- ProductCard declares two inputs: a required name and a price with default 0.
- Its template reads inputs as signals: name(), price().
- ProductList imports ProductCard, then uses <app-product-card> inside @for.
- [name]="p.name" passes data from parent to child.
- Each component’s styles are scoped to its own template.
Real-world use case#
A design system team ships components like <app-button>, <app-card> and <app-data-table>. Feature teams import them and only pass inputs.
Common mistakes#
The parent forgot to add the child component to its imports array.
With signal inputs, {{ name }} shows the function. Use {{ name() }}.
A 1,000-line component mixes concerns. Split it into smaller presentational components.
Best practices#
- One component per file
- Prefix selectors (app-, shop-)
- Use input.required for mandatory data
- Keep components presentational where possible
Remember this#
@Component = selector + template + styles + imports.
input() = data in; read with name().
Using a child? Add it to imports.
Practice exercise#
Your task: Create a UserBadge component with a required name input and an optional role input (default "Member"), showing "Asha (Admin)".
Need a hint?
Show solution
import { Component, input } from '@angular/core';
@Component({
selector: 'app-user-badge',
template: `<span>{{ name() }} ({{ role() }})</span>`,
})
export class UserBadge {
name = input.required<string>();
role = input('Member');
}
// Usage: <app-user-badge name="Asha" role="Admin" />
Mini quiz#
What does the selector define?
Want more? Practise all Angular MCQs · Angular interview questions
My notes#
Saved in this browser.