Key Features of Angular
1. Component-Based Architecture
Angular’s architecture is built around components, which are the fundamental building blocks of Angular applications.
// Example of a component with different features
@Component({
selector: 'app-user-profile',
template: `
<div class="profile-card">
<h2>{{ user.name | titlecase }}</h2>
<p>{{ user.bio }}</p>
<button (click)="updateProfile()">Update</button>
</div>
`,
styles: [`
.profile-card {
padding: 1rem;
border: 1px solid #ddd;
border-radius: 8px;
}
`]
})
export class UserProfileComponent implements OnInit {
user = { name: '', bio: '' };
ngOnInit() {
this.loadUserProfile();
}
loadUserProfile() {
// Load user data
}
}
2. TypeScript Integration
Angular is built with TypeScript, providing strong typing, object-oriented features, and compile-time error checking.
// Interface definition
interface User {
id: number;
name: string;
email: string;
role: 'admin' | 'user';
lastLogin?: Date;
}
// Service with TypeScript
@Injectable({
providedIn: 'root'
})
class UserService {
private users: User[] = [];
getUser(id: number): User | undefined {
return this.users.find(user => user.id === id);
}
addUser(user: Omit<User, 'id'>): User {
const newUser = { ...user, id: this.generateId() };
this.users.push(newUser);
return newUser;
}
}
3. Dependency Injection (DI)
Angular’s DI system helps manage component dependencies and enables better testing and modularity.
// Service definition
@Injectable({
providedIn: 'root'
})
class LoggerService {
log(message: string) {
console.log(`[${new Date().toISOString()}]: ${message}`);
}
}
// Using the service in a component
@Component({
selector: 'app-example'
})
class ExampleComponent {
constructor(
private logger: LoggerService,
private userService: UserService
) {}
performAction() {
this.logger.log('Action performed');
// Use userService
}
}
4. Powerful Template System
Angular’s template syntax provides powerful features for building dynamic UIs.
@Component({
selector: 'app-todo-list',
template: `
<!-- Event Binding -->
<button (click)="addTask()">Add Task</button>
<!-- Property Binding -->
<input [value]="newTask" (input)="newTask = $event.target.value">
<!-- Structural Directives -->
<ul>
<li *ngFor="let task of tasks; let i = index">
<!-- Two-way Binding -->
<input [(ngModel)]="tasks[i]">
<!-- Event with Parameter -->
<button (click)="removeTask(i)">Delete</button>
</li>
</ul>
<!-- Conditional Rendering -->
<p *ngIf="tasks.length === 0">No tasks available</p>
`
})
class TodoListComponent {
tasks: string[] = [];
newTask = '';
addTask() {
if (this.newTask.trim()) {
this.tasks.push(this.newTask);
this.newTask = '';
}
}
removeTask(index: number) {
this.tasks.splice(index, 1);
}
}
5. Forms and Validation
Angular provides two types of forms: Template-driven and Reactive forms.
// Reactive Form Example
@Component({
selector: 'app-registration',
template: `
<form [formGroup]="registrationForm" (ngSubmit)="onSubmit()">
<div>
<input formControlName="email" placeholder="Email">
<div *ngIf="email.invalid && email.touched" class="error">
<span *ngIf="email.errors?.['required']">Email is required</span>
<span *ngIf="email.errors?.['email']">Invalid email format</span>
</div>
</div>
<div>
<input formControlName="password" type="password" placeholder="Password">
<div *ngIf="password.invalid && password.touched" class="error">
<span *ngIf="password.errors?.['minlength']">
Password must be at least 8 characters
</span>
</div>
</div>
<button type="submit" [disabled]="registrationForm.invalid">
Register
</button>
</form>
`
})
class RegistrationComponent {
registrationForm = new FormGroup({
email: new FormControl('', [Validators.required, Validators.email]),
password: new FormControl('', [
Validators.required,
Validators.minLength(8)
])
});
get email() { return this.registrationForm.get('email')!; }
get password() { return this.registrationForm.get('password')!; }
onSubmit() {
if (this.registrationForm.valid) {
console.log(this.registrationForm.value);
}
}
}
6. HTTP Client
Angular provides a powerful HTTP client for making API calls.
@Injectable({
providedIn: 'root'
})
class ApiService {
constructor(private http: HttpClient) {}
// GET request with type safety
getUsers(): Observable<User[]> {
return this.http.get<User[]>('/api/users').pipe(
retry(3),
catchError(this.handleError)
);
}
// POST request with body
createUser(user: Omit<User, 'id'>): Observable<User> {
return this.http.post<User>('/api/users', user).pipe(
catchError(this.handleError)
);
}
private handleError(error: HttpErrorResponse) {
console.error('An error occurred:', error.message);
return throwError(() =>
new Error('Something went wrong; please try again later.'));
}
}
7. Routing and Navigation
Angular’s router enables navigation between views.
// Route configuration
const routes: Routes = [
{
path: 'users',
component: UserListComponent,
children: [
{ path: ':id', component: UserDetailComponent }
],
canActivate: [AuthGuard]
},
{
path: 'admin',
loadChildren: () =>
import('./admin/admin.module').then(m => m.AdminModule),
canLoad: [AdminGuard]
}
];
// Using router in components
@Component({
template: `
<nav>
<a routerLink="/users" routerLinkActive="active">Users</a>
<a [routerLink]="['/users', userId]">User Details</a>
</nav>
<router-outlet></router-outlet>
`
})
class AppComponent {
constructor(private router: Router) {}
navigateToUser(id: number) {
this.router.navigate(['/users', id], {
queryParams: { tab: 'profile' }
});
}
}
8. Standalone Components (Modern Angular)
Angular’s standalone components provide a simpler way to build applications.
// Standalone component
@Component({
standalone: true,
selector: 'app-feature',
imports: [
CommonModule,
RouterModule,
SharedComponentsModule
],
template: `
<div>
<h1>{{ title }}</h1>
<shared-component></shared-component>
</div>
`
})
export class FeatureComponent {
title = 'Feature Component';
}
// Bootstrap standalone application
bootstrapApplication(AppComponent, {
providers: [
provideRouter(routes),
provideHttpClient(),
provideAnimations()
]
}).catch(err => console.error(err));
Interview Tips
When discussing Angular’s key features in an interview:
Emphasize Modern Features:
- Highlight standalone components
- Discuss performance improvements
- Mention modern development practices
Real-world Applications:
- Explain how features solve common problems
- Share examples from your experience
- Discuss scalability benefits
Best Practices:
- Mention Angular’s opinionated nature
- Discuss built-in security features
- Emphasize testing capabilities
Performance Considerations:
- Talk about change detection strategies
- Mention lazy loading capabilities
- Discuss optimization techniques