Angular Components
Read one Angular interview question at a time, then flip for the complete explanation, example, and code.
Read one Angular interview question at a time, then flip for the complete explanation, example, and code.
Angular Interview Questions · Angular Components Companion Article
Angular applications are built from components. A component represents a specific part of the user interface and contains the logic, HTML structure, and styling needed for that part of the application. A small application may contain only a few components, while a large business application can contain hundreds of components organized into a component tree. This chapter explains how Angular components are structured, configured with the @Component decorator, given templates and styles, and combined into a component tree to build real Angular user interfaces.
For example, an e-commerce page might contain separate components for:
Breaking an application into components makes the code easier to understand, test, maintain, and reuse.
An Angular component is a TypeScript class that Angular uses to control a portion of the webpage.
A component normally contains three main parts:
A basic component may look like this:
import { Component } from '@angular/core';
@Component({
selector: 'app-welcome',
template: `<h2>Welcome to Angular</h2>`
})
export class WelcomeComponent {
}
Here:
WelcomeComponent is the component class.@Component() tells Angular that the class is a component.selector defines how the component can be used in another template.template defines the component's HTML.The component can then be used using its selector:
<app-welcome></app-welcome>
When Angular finds this element, it renders the template associated with WelcomeComponent.
Without components, an entire application could become one large collection of HTML and TypeScript code.
Components divide the application into smaller responsibilities.
For example:
Application
│
├── Header
├── Sidebar
├── Product List
│ ├── Product Card
│ ├── Product Card
│ └── Product Card
└── Footer
Each component can focus on one job.
A ProductCardComponent, for example, should normally handle the presentation and behavior of a product card rather than contain unrelated code for authentication, navigation, or application configuration.
This separation makes large Angular applications easier to manage.
A component can be created manually or generated using Angular CLI.
A common command is:
ng generate component product-card
The shorter form is:
ng g c product-card
Angular CLI creates the files required by the component according to the project's configuration.
A generated component commonly includes files such as:
product-card/
├── product-card.ts
├── product-card.html
├── product-card.css
└── product-card.spec.ts
Exact generated filenames and files may vary depending on CLI configuration and options.
A component can also be created directly.
import { Component } from '@angular/core';
@Component({
selector: 'app-profile',
templateUrl: './profile.html',
styleUrl: './profile.css'
})
export class ProfileComponent {
}
Angular needs the component decorator so that it knows how the class should participate in the user interface.
Component names should describe their responsibility clearly.
Good examples:
LoginComponent
ProductCardComponent
UserProfileComponent
OrderHistoryComponent
SearchBarComponent
Less useful names include:
DataComponent
NewComponent
TestComponent
Component1
Clear component names become increasingly important as an Angular application grows.
The @Component() decorator provides Angular with information about a component.
Example:
@Component({
selector: 'app-user',
templateUrl: './user.html',
styleUrl: './user.css'
})
export class UserComponent {
}
The decorator is placed immediately before the component class.
Angular reads the decorator metadata to determine things such as:
The decorator comes from Angular's core package:
import { Component } from '@angular/core';
The configuration inside @Component() is called component metadata.
Example:
@Component({
selector: 'app-dashboard',
templateUrl: './dashboard.html',
styleUrl: './dashboard.css'
})
export class DashboardComponent {
}
The metadata connects the TypeScript class with the visual part of the component.
Common metadata properties include:
| Property | Purpose |
|---|---|
selector | Defines how the component is referenced |
template | Defines inline HTML |
templateUrl | Loads HTML from an external file |
styles | Defines inline component CSS |
styleUrl | References a component stylesheet |
styleUrls | References multiple stylesheets where applicable |
imports | Makes dependencies available to a standalone component |
standalone | Indicates standalone component configuration where explicitly used |
providers | Defines services/providers available in the component injector |
changeDetection | Configures the component's change-detection strategy |
Not every component needs every property.
Use only the metadata required by that component.
The component class contains the data and behavior used by the component.
Example:
import { Component } from '@angular/core';
@Component({
selector: 'app-user',
template: `
<h2>{{ name }}</h2>
<button (click)="changeName()">Change Name</button>
`
})
export class UserComponent {
name = 'Rahul';
changeName(): void {
this.name = 'Amit';
}
}
The class contains:
name = 'Rahul';
This is component data.
It also contains:
changeName(): void {
this.name = 'Amit';
}
This is component behavior.
The template can access public members of the component class.
A component class may contain:
For example:
export class CounterComponent {
count = 0;
increment(): void {
this.count++;
}
decrement(): void {
this.count--;
}
}
The template could use these members:
<h2>{{ count }}</h2>
<button (click)="increment()">+</button>
<button (click)="decrement()">-</button>
A component should not become responsible for every part of the application.
For example, complicated HTTP communication, reusable business rules, caching logic, and application-wide state may belong in services or other dedicated layers rather than directly inside a UI component.
Keeping component responsibilities focused improves maintainability.
The template defines the component's user interface.
A template uses HTML together with Angular template features.
Example:
<h1>{{ title }}</h1>
<p>Welcome, {{ username }}</p>
<button (click)="logout()">Logout</button>
The template can interact with data from the component class.
For example:
export class DashboardComponent {
title = 'Dashboard';
username = 'Dattatray';
logout(): void {
console.log('User logged out');
}
}
Angular connects the class and template.
Values can be displayed using interpolation:
<h2>{{ productName }}</h2>
If the component contains:
productName = 'Laptop';
Angular displays:
Laptop
Templates can also use bindings, events, control-flow features, pipes, child components, and other Angular template functionality.
For larger templates, HTML is usually placed in a separate file.
Component:
@Component({
selector: 'app-login',
templateUrl: './login.html'
})
export class LoginComponent {
}
Template:
<h2>Login</h2>
<label>Email</label>
<input type="email">
<label>Password</label>
<input type="password">
<button>Login</button>
External templates keep TypeScript and HTML separate, which is often easier to maintain when the user interface becomes large.
Angular components can contain styles specifically associated with their templates.
Example:
h2 {
font-size: 24px;
}
button {
padding: 8px 16px;
}
Component:
@Component({
selector: 'app-login',
templateUrl: './login.html',
styleUrl: './login.css'
})
export class LoginComponent {
}
Component styles are useful because each component can maintain its own presentation rules.
Angular applications commonly contain both component-level and global styles.
Use component styles for UI rules specific to one component.
Example:
.product-card {
padding: 20px;
border: 1px solid #ddd;
}
Use global styles for application-wide design rules such as:
A clear styling strategy prevents unrelated components from becoming tightly coupled through CSS.
Instead of using an external HTML file, HTML can be written directly inside the component decorator.
Example:
@Component({
selector: 'app-message',
template: `<p>Angular components are reusable.</p>`
})
export class MessageComponent {
}
For multiline HTML, template literals can be used:
@Component({
selector: 'app-profile',
template: `
<section>
<h2>User Profile</h2>
<p>Name: {{ name }}</p>
<p>Role: {{ role }}</p>
</section>
`
})
export class ProfileComponent {
name = 'Rahul';
role = 'Developer';
}
Inline templates work well for components containing very small amounts of markup.
Examples include:
For a large user interface, external templates are generally easier to read and maintain.
Styles can also be placed directly inside component metadata.
Example:
@Component({
selector: 'app-alert',
template: `<p class="message">Operation completed.</p>`,
styles: [`
.message {
font-weight: bold;
padding: 10px;
}
`]
})
export class AlertComponent {
}
This keeps the TypeScript, HTML, and styles in one file.
It may be useful for very small components.
Suitable when:
Suitable when:
There is no need to force every component to use the same approach. The choice should depend on the size and responsibility of the component.
The selector determines how Angular identifies a component in a template.
Example:
@Component({
selector: 'app-product-card',
template: `<p>Product Card</p>`
})
export class ProductCardComponent {
}
The component can be used as:
<app-product-card></app-product-card>
The browser may initially treat app-product-card as a custom element, and Angular associates it with the corresponding component.
A project-specific prefix is commonly used.
Example:
app-header
app-footer
app-product
app-user-profile
The prefix helps distinguish application components from normal HTML elements and components from other libraries.
Prefer:
app-shopping-cart
app-product-details
app-user-profile
instead of vague selectors such as:
app-box
app-data
app-item2
A selector should indicate what the component represents.
Modern Angular development supports standalone components, allowing components to declare their own template dependencies directly rather than requiring every component to be declared through an NgModule.
Example:
import { Component } from '@angular/core';
@Component({
selector: 'app-home',
standalone: true,
template: `<h1>Home</h1>`
})
export class HomeComponent {
}
Standalone architecture can reduce module-related boilerplate and makes component dependencies easier to see.
Suppose there is a child component:
import { Component } from '@angular/core';
@Component({
selector: 'app-user-card',
standalone: true,
template: `<p>User Card</p>`
})
export class UserCardComponent {
}
A parent component can import it:
import { Component } from '@angular/core';
import { UserCardComponent } from './user-card';
@Component({
selector: 'app-dashboard',
standalone: true,
imports: [UserCardComponent],
template: `
<h1>Dashboard</h1>
<app-user-card></app-user-card>
`
})
export class DashboardComponent {
}
The important relationship is:
DashboardComponent
│
└── imports UserCardComponent
The dashboard can then use the child component's selector in its template.
Standalone components can make dependencies more explicit.
A developer can inspect:
imports: [UserCardComponent]
and immediately understand that the component depends on UserCardComponent.
They are particularly useful for:
Understanding NgModule-based applications is still valuable because many existing Angular projects use them.
Angular applications naturally form a hierarchy known as a component tree.
Consider an online store:
AppComponent
│
├── HeaderComponent
│ ├── LogoComponent
│ └── SearchComponent
│
├── ProductListComponent
│ ├── ProductCardComponent
│ ├── ProductCardComponent
│ └── ProductCardComponent
│
├── CartComponent
│ └── CartItemComponent
│
└── FooterComponent
AppComponent is near the top of the hierarchy.
It contains several child components.
Some of those child components contain their own children.
If one component is placed inside another component's template, a parent-child relationship is created.
Example:
<app-header></app-header>
<app-product-list></app-product-list>
<app-footer></app-footer>
If this template belongs to AppComponent, then:
AppComponent
├── HeaderComponent
├── ProductListComponent
└── FooterComponent
AppComponent is the parent.
The other components are children.
A nested component is a component used inside another component.
Suppose an application contains a reusable product card.
@Component({
selector: 'app-product-card',
standalone: true,
template: `
<div class="product">
<h3>Wireless Mouse</h3>
<p>₹799</p>
</div>
`
})
export class ProductCardComponent {
}
It can be placed inside a product-list component:
import { Component } from '@angular/core';
import { ProductCardComponent } from './product-card';
@Component({
selector: 'app-product-list',
standalone: true,
imports: [ProductCardComponent],
template: `
<h2>Products</h2>
<app-product-card></app-product-card>
<app-product-card></app-product-card>
`
})
export class ProductListComponent {
}
The structure becomes:
ProductListComponent
│
├── ProductCardComponent
└── ProductCardComponent
The same component definition can therefore be reused multiple times.
Consider a dashboard containing three sections:
Dashboard
├── Profile
├── Notifications
└── Recent Orders
Each feature can become a component.
import { Component } from '@angular/core';
@Component({
selector: 'app-profile',
standalone: true,
template: `
<section>
<h2>{{ name }}</h2>
<p>{{ role }}</p>
</section>
`
})
export class ProfileComponent {
name = 'Amit';
role = 'Software Developer';
}
import { Component } from '@angular/core';
@Component({
selector: 'app-notifications',
standalone: true,
template: `
<section>
<h2>Notifications</h2>
<p>You have {{ notificationCount }} new notifications.</p>
</section>
`
})
export class NotificationsComponent {
notificationCount = 3;
}
import { Component } from '@angular/core';
import { ProfileComponent } from './profile';
import { NotificationsComponent } from './notifications';
@Component({
selector: 'app-dashboard',
standalone: true,
imports: [
ProfileComponent,
NotificationsComponent
],
template: `
<h1>Dashboard</h1>
<app-profile></app-profile>
<app-notifications></app-notifications>
`
})
export class DashboardComponent {
}
This approach is easier to maintain than placing the entire dashboard interface and logic inside one large component.
One of the most useful design principles in Angular is giving each component a clear responsibility.
For example:
ProductListComponent
should mainly manage the product-list user interface.
ProductCardComponent
should present an individual product.
CartComponent
should represent the shopping-cart interface.
Problems begin when one component starts handling unrelated responsibilities.
For example, a single component containing:
will usually become difficult to maintain.
Breaking such functionality into appropriate components and services creates clearer boundaries.
There is no rule saying that every few lines of HTML must become a separate component.
Creating too many tiny components can also make an application unnecessarily complicated.
Create a separate component when the UI section:
For example, a complete reusable product card is a strong component candidate.
A single <span> used only once usually does not need its own component.
One major benefit of component architecture is reuse.
Consider:
<app-product-card></app-product-card>
Instead of duplicating product markup across many pages, the application can reuse the same component.
A properly designed reusable component can later receive different data and react to different events.
This leads naturally to Angular concepts such as:
These concepts allow the same component structure to work with different values.
Angular encourages composition.
Instead of building one huge component, an interface can be assembled from smaller components.
For example:
ProductPageComponent
├── ProductGalleryComponent
├── ProductInformationComponent
├── PriceComponent
├── AddToCartComponent
├── ReviewListComponent
└── RelatedProductsComponent
This approach provides several advantages:
For a small component, related files may be grouped together.
product-card/
├── product-card.ts
├── product-card.html
├── product-card.css
└── product-card.spec.ts
For more complicated features, components can be grouped according to the application domain.
Example:
products/
├── product-list/
├── product-card/
├── product-details/
└── product-search/
Grouping components by feature can make large applications easier to navigate than keeping unrelated components in a single folder.
Avoid placing an entire page's business and presentation logic into one extremely large component.
Break meaningful sections into smaller components where appropriate.
Componentization should improve the architecture, not create unnecessary complexity.
Do not create a component simply because an element exists.
Avoid:
BoxComponent
Main2Component
DataComponent
TempComponent
Prefer names that describe business or UI meaning.
Components primarily represent UI behavior and presentation.
Complex reusable business logic is often better handled through services or other dedicated application layers.
When a component uses another component, directive, or pipe, the required dependency must be available in that component's compilation context.
In standalone components, dependencies are commonly added through the component's imports.
If the component selector is:
selector: 'app-user-profile'
use:
<app-user-profile></app-user-profile>
Using a different element name will not refer to that component.
If the same meaningful interface appears repeatedly, consider whether it should become a reusable component rather than copying its markup to several pages.
A page containing everything in one component might look conceptually like:
DashboardComponent
├── Header logic
├── Search logic
├── Profile logic
├── Product logic
├── Notification logic
├── Order logic
└── Footer logic
A better structure could be:
DashboardComponent
├── HeaderComponent
├── SearchComponent
├── ProfileComponent
├── ProductListComponent
├── NotificationsComponent
├── OrderHistoryComponent
└── FooterComponent
The second structure gives each important UI section a clearer responsibility.
At a high level, the process can be understood as:
Component Class
│
▼
@Component Metadata
│
├── Selector
├── Template
└── Styles
│
▼
Angular
│
▼
Rendered User Interface
The class supplies data and behavior.
The metadata tells Angular how the component is configured.
The template describes the HTML.
The styles control presentation.
Angular combines these pieces and renders the result.
A practical component-development process is:
Identify UI responsibility
↓
Create component
↓
Define selector
↓
Create template
↓
Add component data
↓
Add event handling
↓
Add styles
↓
Add required imports
↓
Use component in parent
↓
Test component behavior
Thinking about responsibility before creating the component prevents unnecessary fragmentation.
Suppose a page initially contains:
<header>
...
</header>
<section class="profile">
...
</section>
<section class="orders">
...
</section>
<footer>
...
</footer>
If these sections have independent responsibilities, the application might evolve into:
<app-header></app-header>
<app-profile></app-profile>
<app-order-history></app-order-history>
<app-footer></app-footer>
The page then becomes a composition of components rather than one large block of markup.
Imagine the same user profile appears on:
Without a reusable component, the same HTML and logic might be copied into several files.
If the design changes, developers may have to update every copy.
With a reusable component:
<app-user-profile></app-user-profile>
the implementation can be maintained in one place and reused wherever appropriate.
This is one of the practical reasons component-based architecture works well for large applications.
Component architecture also improves testability.
A focused component can be tested independently for behavior such as:
Smaller components with clear responsibilities are generally easier to test than one component containing many unrelated features.
Consider creating a component when a piece of UI:
Examples:
NavbarComponent
LoginFormComponent
ProductCardComponent
PaginationComponent
UserAvatarComponent
ShoppingCartComponent
NotificationPanelComponent
Do not create components solely to increase the number of files in the project.
A useful naming pattern is:
Feature + Component
Examples:
UserProfileComponent
ProductListComponent
ShoppingCartComponent
PaymentSummaryComponent
OrderHistoryComponent
Selectors can use corresponding kebab-case names:
app-user-profile
app-product-list
app-shopping-cart
app-payment-summary
app-order-history
Consistent naming makes the component structure easier for other developers to understand.
| Concept | Meaning |
|---|---|
| Component | Reusable building block of an Angular UI |
| Component class | Contains data and behavior |
@Component | Decorator defining Angular component metadata |
| Metadata | Configuration describing the component |
| Selector | Identifies the component in templates |
| Template | Defines the component's HTML |
| Styles | Define component presentation |
| Inline template | HTML stored in component metadata |
| External template | HTML stored in a separate file |
| Inline styles | CSS stored directly in component metadata |
| Standalone component | Component that manages dependencies without requiring declaration in an NgModule |
| Parent component | Component containing another component |
| Child component | Component used inside another component |
| Component tree | Hierarchical structure of Angular components |
| Nested component | Component rendered inside another component |
| Component composition | Building larger interfaces from smaller components |
Consider an online shopping application.
A product page might use:
ProductDetailsPageComponent
│
├── HeaderComponent
├── BreadcrumbComponent
├── ProductGalleryComponent
├── ProductDetailsComponent
│ ├── ProductPriceComponent
│ └── AddToCartComponent
├── ReviewListComponent
│ └── ReviewCardComponent
├── RelatedProductsComponent
│ └── ProductCardComponent
└── FooterComponent
This illustrates an important Angular design idea:
A page does not need to be one component. A page can be a composition of multiple components, each responsible for a meaningful part of the interface.
As the application grows, this structure makes features easier to locate, modify, reuse, and test.
Angular components connect TypeScript logic, HTML templates, styles, and metadata into reusable user-interface building blocks.
The most important concepts to understand are:
@Component() supplies Angular-specific metadata.Once components are clear, topics such as data binding, input/output communication, lifecycle hooks, content projection, signals, dependency injection, routing, and change detection become much easier to understand because they all operate around Angular's component model.