Angular in Angular is best learned by connecting the rule to a feature module in a dashboard app. Start with the smallest component or service, observe the output, and then add one realistic constraint so the concept becomes practical.
The key habit for this lesson is to watch template binding as it changes. That makes the topic easier to debug, easier to explain in interviews, and easier to use in real code without memorizing isolated syntax.
Angular is a powerful, open-source web application framework developed and maintained by Google. It's a complete rewrite of AngularJS (Angular 1.x) and is built using TypeScript. Angular provides a comprehensive solution for building dynamic, single-page applications (SPAs) with features like two-way data binding, dependency injection, routing, forms, HTTP client, and much more.
Angular follows the Model-View-Controller (MVC) architectural pattern and uses a component-based architecture. As of Angular 21 (the latest version), the framework has embraced standalone components by default, eliminating the need for NgModules in most cases. This makes Angular applications simpler, more modular, and easier to understand.
Before starting with Angular, ensure you have the following installed and basic knowledge:
# Check Node.js version (should be 20.19+ or 22.11+)
node --version
# Output: v22.11.0
# Check npm version
npm --version
# Output: 10.9.0
# If Node.js is not installed, download from nodejs.org
# Choose the LTS (Long Term Support) version
The Angular CLI (Command Line Interface) is a powerful tool that helps you create, develop, test, and deploy Angular applications. It automates many development tasks and follows Angular best practices.
# Install Angular CLI globally (one-time setup)
npm install -g @angular/cli
# Verify installation
ng version
# Output: Angular CLI: 21.0.0 (or latest version)
# Get help on available commands
ng help
# Update Angular CLI to latest version (if already installed)
npm update -g @angular/cli
Use the ng new command to create a new Angular project. The CLI will ask you a few questions about routing and styling preferences.
The ng serve command compiles your application, starts a development server, and watches for file changes. Any changes you make will automatically reload the browser.
# Create a new Angular project
ng new my-first-app
# The CLI will ask:
# ? Would you like to add Angular routing? (y/N) → Press Y
# ? Which stylesheet format would you like to use? → Choose CSS (or SCSS)
# Navigate into the project directory
cd my-first-app
# Start the development server
ng serve
# Or start and automatically open in browser
ng serve --open
# The app will be available at: http://localhost:4200/
Angular 21 uses standalone components by default, which simplifies the project structure by eliminating the need for NgModules in most cases.
my-first-app/
├── node_modules/ # Dependencies (auto-generated, don't edit)
├── src/ # Source code directory
│ ├── app/ # Application code
│ │ ├── app.component.ts # Root component (TypeScript)
│ │ ├── app.component.html # Root component template
│ │ ├── app.component.css # Root component styles
│ │ ├── app.component.spec.ts # Unit tests for root component
│ │ ├── app.config.ts # App-level configuration (replaces AppModule)
│ │ └── app.routes.ts # Routing configuration
│ ├── assets/ # Static files (images, fonts, etc.)
│ ├── index.html # Main HTML file
│ ├── main.ts # Application entry point (bootstraps app)
│ └── styles.css # Global styles
├── angular.json # Angular CLI workspace configuration
├── package.json # npm dependencies and scripts
├── tsconfig.json # TypeScript compiler configuration
├── tsconfig.app.json # TypeScript config for the app
└── README.md # Project documentation
Key Files:
- main.ts: Bootstraps the application
- app.config.ts: Provides app-level services and configuration
- app.component.ts: Root component of your application
- app.routes.ts: Defines application routes
In Angular 21, components are standalone by default. The root component is defined in app.component.ts and uses the new Signals API for reactive state management.
// app.component.ts - Root standalone component
import { Component, signal } from '@angular/core';
import { RouterOutlet } from '@angular/router';
@Component({
selector: 'app-root',
standalone: true,
imports: [RouterOutlet],
template: `
<div class="container">
<h1>{{ title() }}</h1>
<p>Welcome to Angular 21!</p>
<div class="counter">
<p>Count: {{ count() }}</p>
<button (click)="increment()">Increment</button>
</div>
<router-outlet></router-outlet>
</div>
`,
styles: [`
.container { padding: 20px; }
h1 { color: #dd0031; }
.counter { margin: 20px 0; }
button {
padding: 10px 20px;
background: #dd0031;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
`]
})
export class AppComponent {
// Using Signals for reactive state (Angular 16+)
title = signal('My First Angular App');
count = signal(0);
// Method to increment counter
increment() {
this.count.update(value => value + 1);
}
// Method to change title
changeTitle(newTitle: string) {
this.title.set(newTitle);
}
}
// main.ts - Application entry point
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app/app.component';
import { appConfig } from './app/app.config';
// Bootstrap the standalone root component
bootstrapApplication(AppComponent, appConfig)
.catch(err => console.error(err));
// In older Angular versions (pre-standalone), you would bootstrap a module:
// platformBrowserDynamic().bootstrapModule(AppModule)
// app.config.ts - Application configuration
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideHttpClient } from '@angular/common/http';
import { routes } from './app.routes';
export const appConfig: ApplicationConfig = {
providers: [
provideZoneChangeDetection({ eventCoalescing: true }),
provideRouter(routes),
provideHttpClient(), // HTTP client is auto-provided in Angular 21
// Add other app-level providers here
]
};
// This replaces the old AppModule approach
// Providers are now configured here instead of in @NgModule
The Angular CLI provides commands for generating components, services, and other Angular artifacts, as well as building and testing your application.
| Command | Description | Example |
|---|---|---|
| ng new | Create a new Angular project | ng new my-app |
| ng serve | Start dev server (localhost:4200) | ng serve --open |
| ng generate component | Generate a new component | ng g c header |
| ng generate service | Generate a new service | ng g s data |
| ng generate pipe | Generate a new pipe | ng g p currency |
| ng generate directive | Generate a new directive | ng g d highlight |
| ng build | Build for production | ng build --configuration production |
| ng test | Run unit tests (Vitest in Angular 21) | ng test |
| ng lint | Run linting | ng lint |
| ng update | Update Angular and dependencies | ng update @angular/core |
| ng version | Show Angular CLI version | ng version |
| ng add | Add a library to your project | ng add @angular/material |
Components are the building blocks of Angular applications. Let's create a simple "Hello" component.
# Generate a new standalone component
ng generate component hello
# Shorthand
ng g c hello
# This creates:
# - src/app/hello/hello.component.ts
# - src/app/hello/hello.component.html
# - src/app/hello/hello.component.css
# - src/app/hello/hello.component.spec.ts
// hello.component.ts - Generated component
import { Component, Input, signal } from '@angular/core';
@Component({
selector: 'app-hello',
standalone: true,
template: `
<div class="hello-box">
<h2>Hello, {{ name() }}!</h2>
<p>You've been greeted {{ greetCount() }} times.</p>
<button (click)="greet()">Greet Again</button>
</div>
`,
styles: [`
.hello-box {
padding: 20px;
border: 2px solid #dd0031;
border-radius: 8px;
margin: 20px 0;
}
button {
background: #dd0031;
color: white;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
}
`]
})
export class HelloComponent {
@Input() name = signal('World'); // Input property with signal
greetCount = signal(0);
greet() {
this.greetCount.update(count => count + 1);
}
}
// app.component.ts - Import and use the component
import { Component } from '@angular/core';
import { HelloComponent } from './hello/hello.component';
@Component({
selector: 'app-root',
standalone: true,
imports: [HelloComponent], // Import the component
template: `
<h1>My Angular App</h1>
<app-hello [name]="'Alice'"></app-hello>
<app-hello [name]="'Bob'"></app-hello>
`
})
export class AppComponent {}
Visual Studio Code is the recommended editor for Angular development. Install these essential extensions:
Now that you have Angular set up, here's what to learn next:
Use Angular when the program needs a clear answer to a specific problem, not because the keyword looks familiar. In a real Angular task, first name the input, then name the transformation, then name the output. This small discipline shows whether the topic is being used correctly or only copied from an example.
A reliable practice flow is: create the smallest working component or service, add one normal case, add one edge case such as missing, repeated, empty, or boundary input, and then confirm the result with browser console and Angular error output. If the result surprises you, reduce the code until the behavior is visible again.
The most common trap here is copying the syntax before understanding the behavior. Avoid it by writing one sentence before the code that explains why Angular is the right choice. After the code runs, verify the lesson by doing this: change one input and explain the changed output.
Copying the syntax before understanding the behavior.
Write the expected behavior first, then make the example prove it.
Practicing only the perfect input.
Also test missing, repeated, empty, or boundary input before considering the lesson complete.
Looking only at the final output.
Trace template binding through each important step.
Use it when the problem matches the behavior shown in the example and when the result can be verified through browser console and Angular error output.
Start with a tiny case, then test missing, repeated, empty, or boundary input. The main warning sign is copying the syntax before understanding the behavior.
Trace template binding, predict the result, run the example, and compare your prediction with the actual output.
Explore 500+ free tutorials across 20+ languages and frameworks.