100 Most Frequently Asked Angular Interview Questions & Answers
Here’s a senior-level Angular interview guide, progressing from fundamentals to Angular architecture, RxJS, performance, testing, security, and modern Angular.
1. Angular Fundamentals
1. What is Angular?
Angular is a TypeScript-based frontend framework developed by Google for building scalable web applications, particularly single-page applications (SPAs). It provides built-in support for components, routing, dependency injection, forms, HTTP communication, and reactive programming.
2. What is the difference between Angular and AngularJS?
AngularJS is the original JavaScript-based framework, while modern Angular is TypeScript-based and component-oriented.
Key differences:
- Angular uses components instead of controllers.
- Angular uses TypeScript.
- Angular has improved dependency injection.
- Angular provides better performance.
- Angular uses RxJS extensively.
- Modern Angular supports standalone components.
- AngularJS used
$scope; Angular does not.
3. What are the main building blocks of Angular?
The major building blocks are:
- Components
- Templates
- Directives
- Pipes
- Services
- Dependency Injection
- Modules
- Routing
- Forms
- HTTP Client
Modern Angular applications can use standalone components, reducing the need for NgModules.
4. What is a component?
A component controls a portion of the application’s UI.
A component typically consists of:
@Component({
selector: 'app-user',
templateUrl: './user.component.html',
styleUrls: ['./user.component.css']
})
export class UserComponent {
}
It contains:
- TypeScript class
- HTML template
- CSS styles
- Metadata
5. What is a standalone component?
A standalone component can be used without declaring it inside an NgModule.
@Component({
selector: 'app-user',
standalone: true,
imports: [CommonModule],
template: `<h1>Hello</h1>`
})
export class UserComponent {}
Standalone APIs simplify application structure and make dependency boundaries more explicit.
6. What is an Angular template?
A template defines the UI associated with a component.
Example:
<h1>{{ title }}</h1>
<button (click)="save()">Save</button>
Angular extends HTML with features such as:
- Interpolation
- Property binding
- Event binding
- Two-way binding
- Structural/control flow
- Pipes
7. What is interpolation?
Interpolation displays component data in the template.
HTML
<h1>{{ username }}</h1>
Angular evaluates the expression and renders its result.
8. What is property binding?
Property binding binds a component property to an HTML or component property.
<img [src]="imageUrl">
<button [disabled]="isDisabled">Save</button>
9. What is event binding?
Event binding allows the template to respond to events.
HTML
<button (click)="save()">Save</button>
The event is passed from the DOM to the component.
10. What is two-way binding?
Two-way binding synchronizes data between the component and template.
The classic syntax is:
HTML
<input [(ngModel)]="username">
It combines property binding and event binding.
2. Components and Directives
11. What is a directive?
A directive changes the behavior or appearance of DOM elements.
There are three main types:
- Components
- Attribute directives
- Structural directives
12. What is an attribute directive?
An attribute directive changes the appearance or behavior of an existing element.
Examples include:
<div [ngClass]="classes"></div>
<div [ngStyle]="styles"></div>
You can also create custom directives.
13. What is a structural directive?
A structural directive changes the DOM structure.
Traditional examples:
<div *ngIf="isLoggedIn"></div>
<div *ngFor="let user of users"></div>
Modern Angular also provides built-in control-flow syntax:
@if (isLoggedIn) {
<p>Welcome</p>
}
@for (user of users; track user.id) {
<p>{{ user.name }}</p>
}
14. What is the difference between a component and directive?
A component is a directive with its own template.
| Component | Directive |
|---|---|
| Has template | Usually no template |
| Controls UI | Modifies existing UI |
Uses @Component | Uses @Directive |
15. What is @Input()?
@Input() allows a parent component to pass data to a child.
TypeScript
@Input() user!: User;
Parent:
HTML
<app-user [user]="selectedUser"></app-user>
16. What is @Output()?
@Output() allows a child component to communicate events to its parent.
TypeScript
@Output() saved = new EventEmitter<User>();
Template:
HTML
<app-user (saved)="handleSave($event)"></app-user>
17. How do parent and child components communicate?
Common approaches include:
@Input@Output- Shared services
- Signals
- Router parameters
- State-management libraries
For simple parent-child communication, Input and Output are usually preferred.
18. What is ViewChild?
ViewChild provides access to a child component, directive, or DOM element.
@ViewChild(UserComponent)
userComponent!: UserComponent;
It should be used carefully because excessive direct component/DOM manipulation can create tight coupling.
19. What is ContentChild?
ContentChild retrieves an element or directive projected into a component using content projection.
It is commonly used with:
HTML
<ng-content></ng-content>
20. What is content projection?
Content projection allows a component to receive HTML content from its parent.
Child:
<div class="card">
<ng-content></ng-content>
</div>
Parent:
<app-card>
<h2>Hello</h2>
</app-card>
3. Angular Lifecycle
21. What are Angular lifecycle hooks?
Common lifecycle hooks include:
ngOnChangesngOnInitngDoCheckngAfterContentInitngAfterContentCheckedngAfterViewInitngAfterViewCheckedngOnDestroy
22. What is ngOnInit()?
ngOnInit() runs once after Angular initializes the component’s input properties.
Typical usage:
ngOnInit() {
this.loadUsers();
}
23. What is ngOnChanges()?
ngOnChanges() runs when an @Input() property changes.
ngOnChanges(changes: SimpleChanges) {
console.log(changes);
}
24. What is ngOnDestroy()?
ngOnDestroy() executes immediately before Angular destroys a component.
It’s commonly used for cleanup:
ngOnDestroy() {
this.subscription.unsubscribe();
}
Modern Angular also provides utilities such as takeUntilDestroyed() to simplify subscription cleanup.
25. What is the difference between ngOnInit and constructor?
The constructor is used primarily for object construction and dependency injection.
ngOnInit() is designed for initialization logic after Angular has initialized inputs.
Generally:
TypeScript
constructor(private service: UserService) {}
and:
ngOnInit() {
this.loadUsers();
}
4. Dependency Injection
26. What is Dependency Injection in Angular?
Dependency Injection allows Angular to create and provide dependencies to classes.
TypeScript
constructor(private userService: UserService) {}
Angular creates the service and injects it into the component.
27. What is an Angular service?
A service is a reusable class containing application logic or shared functionality.
@Injectable({
providedIn: 'root'
})
export class UserService {
}
Services are commonly used for:
- API communication
- Business logic
- State sharing
- Authentication
- Logging
28. What does providedIn: 'root' mean?
@Injectable({
providedIn: 'root'
})
registers the service with the application’s root injector.
Normally, this results in a singleton service instance for the application.
29. What is hierarchical dependency injection?
Angular supports hierarchical injectors.
A dependency can be provided at different levels:
- Root
- Application
- Route
- Component
- Directive
This allows different parts of an application to have different service instances.
30. What is the difference between useClass, useValue, useFactory, and useExisting?
Example:
providers: [
{ provide: Logger, useClass: ProductionLogger },
{ provide: API_URL, useValue: 'https://api.example.com' },
{ provide: Config, useFactory: configFactory },
{ provide: Alias, useExisting: ExistingService }
]
They provide different strategies for resolving dependencies.
5. Routing
31. What is Angular Router?
Angular Router enables navigation between views without performing a full browser page reload.
Example:
const routes: Routes = [
{ path: 'users', component: UsersComponent },
{ path: 'users/:id', component: UserComponent }
];
32. What is lazy loading?
Lazy loading loads application features only when they are needed.
Modern Angular can lazy-load standalone components:
{
path: 'admin',
loadComponent: () =>
import('./admin.component')
.then(m => m.AdminComponent)
}
This can reduce the initial bundle size.
33. What is route guarding?
Route guards control whether navigation is allowed.
Examples include:
CanActivateCanActivateChildCanDeactivateCanMatch
Typical use cases include authorization and unsaved-form protection.
34. What is CanActivate?
CanActivate determines whether a route can be activated.
export const authGuard: CanActivateFn = () => {
return inject(AuthService).isAuthenticated();
};
35. What is CanDeactivate?
CanDeactivate can prevent users from leaving a route.
Typical example:
“You have unsaved changes. Are you sure you want to leave?“
36. What are route parameters?
Route parameters are values embedded in the URL.
/users/123
Route:
TypeScript
{ path: 'users/:id', component: UserComponent }
You can retrieve the ID using ActivatedRoute.
37. What is the difference between route parameters and query parameters?
Route parameter:
/users/123
Query parameter:
/users?page=2&sort=name
Route parameters generally identify a resource, while query parameters commonly control filtering, sorting, pagination, etc.
38. What is a resolver?
A resolver retrieves data before a route is activated.
This can be useful when the page requires data before rendering.
6. RxJS
39. What is RxJS?
RxJS is a library for reactive programming using Observables.
Angular uses RxJS heavily for:
- HTTP
- Router events
- Reactive forms
- Event streams
- Asynchronous operations
40. What is an Observable?
An Observable represents a stream of values over time.
TypeScript
users$: Observable<User[]>;
An Observable can emit:
- zero values
- one value
- many values
- errors
- completion
41. Observable vs Promise?
| Observable | Promise |
|---|---|
| Multiple values | Usually one value |
| Lazy | Eager |
| Can be cancelled by unsubscribing | Not directly cancellable |
| Rich operators | Limited operators |
| Supports streams | Single async result |
42. What is a Subject?
A Subject is both an Observable and an Observer.
const subject = new Subject<string>();
subject.subscribe(value => console.log(value));
subject.next('Hello');
43. What is a BehaviorSubject?
A BehaviorSubject stores the latest value and immediately emits it to new subscribers.
TypeScript
const state$ = new BehaviorSubject<number>(0);
It is frequently used for simple application state.
44. What is ReplaySubject?
A ReplaySubject can replay previous emitted values to new subscribers.
TypeScript
const subject = new ReplaySubject<string>(2);
The 2 means it retains the last two values.
45. What is switchMap()?
switchMap() switches to a new Observable and unsubscribes from the previous one.
It is especially useful for search:
searchTerms.pipe(
switchMap(term => this.api.search(term))
);
If a user types quickly, previous requests can be abandoned.
46. What is mergeMap()?
mergeMap() subscribes to inner Observables concurrently.
Useful when multiple operations can run simultaneously.
47. What is concatMap()?
concatMap() executes inner Observables sequentially.
It is useful when order matters.
48. What is exhaustMap()?
exhaustMap() ignores new emissions while the current Observable is running.
It is useful for preventing duplicate submissions:
clicks.pipe(
exhaustMap(() => this.save())
);
49. Explain switchMap, mergeMap, concatMap, and exhaustMap.
| Operator | Behavior | Typical use |
|---|---|---|
switchMap | Cancel previous | Search |
mergeMap | Run concurrently | Independent requests |
concatMap | Queue sequentially | Ordered writes |
exhaustMap | Ignore new until done | Submit button |
50. What is debounceTime()?
debounceTime() waits until no new value has arrived for a specified duration.
search$.pipe(
debounceTime(300)
)
Commonly used for autocomplete/search fields.
7. Angular Forms
51. What types of forms does Angular support?
Angular supports:
- Template-driven forms
- Reactive forms
52. Reactive vs template-driven forms?
| Reactive | Template-driven |
|---|---|
| Explicit model | Implicit model |
| TypeScript-centric | HTML-centric |
| Easier testing | Simpler for small forms |
| Better for complex forms | Good for simple forms |
For enterprise applications, reactive forms are often preferred.
53. What is FormControl?
A FormControl represents the value and validation state of an individual form field.
TypeScript
name = new FormControl('');
54. What is FormGroup?
A FormGroup groups multiple controls.
form = new FormGroup({
name: new FormControl(''),
email: new FormControl('')
});
55. What is FormArray?
FormArray represents a dynamic collection of controls.
skills = new FormArray([
new FormControl('Java'),
new FormControl('Angular')
]);
Useful when the number of fields is dynamic.
56. What are validators?
Validators enforce constraints on form values.
name = new FormControl('', [
Validators.required,
Validators.minLength(3)
]);
57. What are async validators?
Async validators perform asynchronous validation.
Examples:
- Username availability
- Server-side validation
- Duplicate email checking
8. HTTP and APIs
58. What is HttpClient?
HttpClient provides HTTP communication.
constructor(private http: HttpClient) {}
getUsers() {
return this.http.get<User[]>('/api/users');
}
59. Does HttpClient return Observables?
Yes.
TypeScript
this.http.get<User[]>('/api/users')
returns an Observable.
The request generally executes when the Observable is subscribed to.
60. What is an HTTP interceptor?
An interceptor can inspect and modify HTTP requests and responses.
Common uses:
- Authentication
- JWT tokens
- Logging
- Error handling
- Retry logic
- Request correlation IDs
61. How do you add an authorization token?
An interceptor can clone the request:
const request = req.clone({
setHeaders: {
Authorization: `Bearer ${token}`
}
});
return next(request);
62. How do you handle HTTP errors?
Use RxJS operators such as catchError().
return this.http.get('/api/users').pipe(
catchError(error => {
console.error(error);
return throwError(() => error);
})
);
9. Change Detection
63. What is change detection?
Change detection determines when Angular needs to update the DOM because application state has changed.
64. What is ChangeDetectionStrategy.OnPush?
OnPush reduces unnecessary change detection.
@Component({
changeDetection: ChangeDetectionStrategy.OnPush
})
Angular checks the component primarily when:
- An input reference changes
- An event occurs in the component
- An observable used by
asyncemits - A signal read by the template changes
- Change detection is explicitly triggered
65. Why should immutable data be used with OnPush?
Consider:
TypeScript
this.user.name = 'Bill';
The object reference hasn’t changed.
Instead:
this.user = {
...this.user,
name: 'Bill'
};
creates a new reference, making change detection easier to reason about.
66. What is ChangeDetectorRef?
ChangeDetectorRef provides APIs for controlling change detection.
Common methods include:
markForCheck()
detectChanges()
detach()
reattach()
67. What is zone-based change detection?
Historically Angular used zone.js to detect asynchronous operations and trigger change detection.
Modern Angular increasingly supports zoneless change detection, allowing applications to avoid relying on ZoneJS for change detection.
10. Signals
68. What are Angular Signals?
Signals are Angular’s reactive primitive for representing state.
TypeScript
count = signal(0);
Read the value:
TypeScript
count()
Update it:
TypeScript
count.set(10);
69. What is computed()?
computed() creates derived state.
firstName = signal('Bill');
lastName = signal('Liao');
fullName = computed(
() => `${firstName()} ${lastName()}`
);
70. What is effect()?
effect() executes side-effect logic when signals it reads change.
effect(() => {
console.log(this.count());
});
It should generally be used for side effects rather than deriving state.
71. Signals vs RxJS?
Signals are primarily useful for synchronous reactive state.
RxJS is better suited to:
- asynchronous streams
- events
- HTTP workflows
- complex stream composition
They are complementary rather than mutually exclusive.
72. What are toSignal() and toObservable()?
Angular provides interoperability between Signals and RxJS.
Conceptually:
TypeScript
const user = toSignal(user$);
converts an Observable into a Signal.
And:
TypeScript
const user$ = toObservable(user);
converts a Signal into an Observable.
11. Pipes
73. What is a pipe?
A pipe transforms data in templates.
HTML
{{ price | currency }}
74. What is a custom pipe?
You can create custom transformations:
@Pipe({
name: 'capitalize'
})
export class CapitalizePipe {
transform(value: string) {
return value.charAt(0).toUpperCase() + value.slice(1);
}
}
75. What is a pure pipe?
A pure pipe runs only when its input changes by value/reference according to Angular’s change detection rules.
Pure pipes are preferred for deterministic transformations.
76. What is an impure pipe?
An impure pipe can run during every change-detection cycle.
@Pipe({
name: 'myPipe',
pure: false
})
Impure pipes should be used carefully because they can negatively affect performance.
12. Angular Modules
77. What is an NgModule?
An NgModule groups Angular declarations, imports, providers, and exports.
Example:
@NgModule({
declarations: [],
imports: [],
providers: [],
exports: []
})
export class UserModule {}
78. Are NgModules still required?
No.
Modern Angular supports standalone components, directives, and pipes.
NgModules remain supported, particularly in existing applications and libraries.
79. What is CommonModule?
CommonModule historically provided common Angular directives and pipes such as:
NgIfNgForNgClassAsyncPipe
With modern standalone Angular, dependencies can be imported more directly.
80. What is a shared module?
A SharedModule traditionally contains reusable components, directives, and pipes.
However, in modern standalone Angular applications, reusable standalone components/directives/pipes can often replace the need for a SharedModule.
13. Performance
81. How do you improve Angular application performance?
Common techniques:
- Lazy loading
OnPush- Signals
- Efficient list rendering
track/trackBy- Avoid expensive template expressions
- Code splitting
- Image optimization
- SSR/SSG where appropriate
- Caching
- Avoid unnecessary subscriptions
- Virtual scrolling
- Bundle analysis
82. What is trackBy?
trackBy helps Angular identify list items efficiently.
Traditional syntax:
<div *ngFor="let user of users; trackBy: trackById">
{{ user.name }}
</div>
trackById(index: number, user: User) {
return user.id;
}
Modern control flow uses:
@for (user of users; track user.id) {
{{ user.name }}
}
83. How can you optimize large lists?
Use:
@for (...; track item.id)- OnPush
- Virtual scrolling
- Pagination
- Server-side filtering
- Avoid unnecessary object recreation
- Incremental rendering where appropriate
84. What is lazy loading and why does it improve performance?
Lazy loading splits application code into smaller chunks and loads them when required.
Instead of downloading the entire application initially, users download only what they need.
85. What is Angular SSR?
Angular SSR renders pages on the server before sending HTML to the browser.
Benefits include:
- Improved initial rendering
- Better SEO
- Improved perceived performance
Angular also supports hybrid rendering strategies where different routes can use different rendering approaches.
14. State Management
86. What is state management?
State management controls application data and its lifecycle.
Examples include:
- Component state
- Service-based state
- Signals
- RxJS
- NgRx
- Other state-management libraries
87. What is NgRx?
NgRx is a reactive state-management ecosystem for Angular inspired by Redux.
Core concepts include:
- Store
- Actions
- Reducers
- Selectors
- Effects
88. What is a reducer?
A reducer calculates the next state from the current state and an action.
Conceptually:
current state + action → new state
Reducers should be predictable and free of side effects.
89. What is an NgRx Effect?
An Effect handles side effects such as:
- HTTP calls
- External APIs
- Logging
- Navigation
Example flow:
Action
↓
Effect
↓
HTTP API
↓
Success Action
↓
Reducer
↓
Store
90. When should you use NgRx?
NgRx is useful when:
- State is shared across many features
- State transitions are complex
- Debugging state history matters
- Multiple asynchronous workflows exist
- The application benefits from strict state conventions
For small applications, a service + signals may be simpler.
15. Testing
91. How do you test Angular applications?
Angular applications can be tested at multiple levels:
- Unit tests
- Component tests
- Service tests
- Integration tests
- End-to-end tests
Popular tooling includes Angular’s current testing APIs plus ecosystem tools such as Jest and Playwright.
92. What is TestBed?
TestBed provides an Angular testing environment.
Example:
TestBed.configureTestingModule({
imports: [UserComponent],
providers: [UserService]
});
It can create components and inject dependencies for tests.
93. How do you test a service?
Example:
TypeScript
const service = TestBed.inject(UserService);
Then test its methods and behavior.
For HTTP services, Angular provides HTTP testing utilities that allow requests to be intercepted and mocked.
94. How do you test HTTP calls?
You can use Angular’s HTTP testing support.
Conceptually:
const req = httpTestingController.expectOne('/api/users');
req.flush([
{ id: 1, name: 'Bill' }
]);
This allows tests to verify HTTP behavior without calling a real backend.
16. Security
95. How does Angular protect against XSS?
Angular automatically sanitizes many values inserted into templates.
For example:
HTML
<div>{{ userInput }}</div>
Angular treats the value as text rather than arbitrary HTML.
Developers should still avoid bypassing Angular’s sanitization unnecessarily.
96. What is DomSanitizer?
DomSanitizer provides APIs for working with values that Angular normally sanitizes.
For example:
TypeScript
constructor(private sanitizer: DomSanitizer) {}
Methods such as bypassSecurityTrustHtml() should be used only when the input is trusted and the security implications are understood.
97. How should authentication be implemented in Angular?
A typical enterprise architecture uses:
Angular
↓
Authentication Provider / Identity Provider
↓
Access Token
↓
HTTP Interceptor
↓
Backend API
Angular should not be responsible for enforcing authorization. The backend must always enforce access control.
17. Advanced Angular
98. What is Angular Universal?
Angular Universal was the historical name for Angular server-side rendering.
Modern Angular provides SSR capabilities directly through Angular’s current application tooling.
SSR allows Angular applications to render HTML on the server.
99. What is hydration?
Hydration allows Angular to reuse server-rendered HTML on the client rather than completely recreating the DOM.
Typical flow:
Server
↓
HTML
↓
Browser
↓
Hydration
↓
Interactive Angular Application
Hydration can significantly improve initial rendering performance for SSR applications.
100. How would you architect a large enterprise Angular application?
A strong enterprise architecture might look like:
Angular Application
│
┌─────────────┴─────────────┐
│ │
Presentation Application
│ │
Components / UI Facades / State
│ │
└─────────────┬─────────────┘
│
Domain Services
│
Infrastructure
│
┌─────────────┼─────────────┐
│ │ │
REST API WebSocket Storage
│
Backend Services
│
Microservices
For a modern enterprise Angular application, I would typically consider:
- Standalone components
- Feature-based architecture
- Lazy-loaded routes
- Signals for local/UI state
- RxJS for asynchronous streams
OnPushor zoneless-friendly patterns- Typed reactive forms
- HTTP interceptors
- Route guards
- Centralized error handling
- Consistent API contracts
- Automated unit/integration/E2E testing
- SSR/hydration where beneficial
- Accessibility
- Security
- CI/CD
- Observability
- Clear separation between presentation, application, domain, and infrastructure concerns