Angular Interview Questions


51 Angular Questions to Pass Any Interview: A Comprehensive Guide
Table of Contents
Component Architecture & Communication
1. What are the various ways of Component communications?
Angular provides several methods for component communication[70][73]:
Parent to Child Communication:
// Parent Component
@Component({
template: `<app-child [data]="parentData"></app-child>`
})
export class ParentComponent {
parentData = 'Hello from Parent';
}
// Child Component
@Component({
selector: 'app-child'
})
export class ChildComponent {
@Input() data: string;
}
Child to Parent Communication:
// Child Component
@Component({
selector: 'app-child'
})
export class ChildComponent {
@Output() messageEvent = new EventEmitter<string>();
sendMessage() {
this.messageEvent.emit('Hello from Child');
}
}
// Parent Component
@Component({
template: `<app-child (messageEvent)="receiveMessage($event)"></app-child>`
})
export class ParentComponent {
receiveMessage(message: string) {
console.log(message);
}
}
Service-based Communication:
@Injectable({ providedIn: 'root' })
export class DataService {
private messageSource = new BehaviorSubject<string>('Initial Message');
currentMessage = this.messageSource.asObservable();
changeMessage(message: string) {
this.messageSource.next(message);
}
}
2. What do you understand by life cycle hooks of a Component?
Angular components have a well-defined lifecycle managed by Angular[37][40]:
@Component({
selector: 'app-lifecycle'
})
export class LifecycleComponent implements OnInit, OnChanges, OnDestroy {
@Input() inputValue: string;
// Called after data-bound input properties change
ngOnChanges(changes: SimpleChanges): void {
console.log('Input changed:', changes);
}
// Called once after component initialization
ngOnInit(): void {
console.log('Component initialized');
}
// Called during every change detection run
ngDoCheck(): void {
console.log('Change detection run');
}
// Called once before component destruction
ngOnDestroy(): void {
console.log('Component destroyed');
}
}
3. Which one will be called first, ngOnChange or ngOnInit? Explain with a scenario.
ngOnChanges is called first[37][46]. Here's the execution order:
@Component({
selector: 'app-example'
})
export class ExampleComponent implements OnInit, OnChanges {
@Input() userData: any;
ngOnChanges(changes: SimpleChanges): void {
console.log('1. ngOnChanges called first');
// Called whenever @Input properties change
}
ngOnInit(): void {
console.log('2. ngOnInit called second');
// Called once after first ngOnChanges
}
}
Scenario: When a parent passes data to a child component, Angular first detects the input change (triggering ngOnChanges), then initializes the component (triggering ngOnInit).
7. What do you understand by ViewChild and ContentChild?
ViewChild accesses elements within the component's template, while ContentChild accesses projected content[38][41]:
// ViewChild Example
@Component({
selector: 'app-parent',
template: `
<app-child #childRef></app-child>
<input #inputRef>
`
})
export class ParentComponent implements AfterViewInit {
@ViewChild('childRef') childComponent: ChildComponent;
@ViewChild('inputRef') inputElement: ElementRef;
ngAfterViewInit() {
console.log(this.childComponent); // Access child component
console.log(this.inputElement.nativeElement); // Access DOM element
}
}
// ContentChild Example
@Component({
selector: 'app-container',
template: `
<div>
<h3>Container</h3>
<ng-content></ng-content>
</div>
`
})
export class ContainerComponent implements AfterContentInit {
@ContentChild(ChildComponent) projectedChild: ChildComponent;
ngAfterContentInit() {
console.log(this.projectedChild); // Access projected content
}
}
// Usage
@Component({
template: `
<app-container>
<app-child></app-child>
</app-container>
`
})
export class AppComponent {}
34. Can you explain difference between ContentChild and ViewChild
Key Differences:
ViewChild | ContentChild |
Accesses elements in component's template | Accesses projected content via <ng-content> |
Available in ngAfterViewInit() | Available in ngAfterContentInit() |
Direct template children | Content projection children |
Lazy Loading & Module System
14. What do you understand by lazy loaded modules?
Lazy loading defers module loading until needed, improving initial app performance[24][27][30]:
// App Routing Module
const routes: Routes = [
{
path: 'feature',
loadChildren: () => import('./feature/feature.module').then(m => m.FeatureModule)
},
{
path: 'admin',
loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule)
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {}
// Feature Module
@NgModule({
declarations: [FeatureComponent],
imports: [
CommonModule,
RouterModule.forChild([
{ path: '', component: FeatureComponent }
])
]
})
export class FeatureModule {}
15. For a service how many objects Angular creates for lazy loaded modules?
Angular creates one instance per injector hierarchy[25][28]. For lazy-loaded modules:
// Service provided at root level - ONE instance across entire app
@Injectable({ providedIn: 'root' })
export class GlobalService {}
// Service provided at module level - ONE instance per module
@NgModule({
providers: [ModuleLevelService]
})
export class LazyModule {}
// Service provided at component level - ONE instance per component
@Component({
providers: [ComponentLevelService]
})
export class MyComponent {}
17. How to dynamically load a component? can you explain me the process?
Dynamic component loading allows runtime component creation[101][104][107]:
// Dynamic Component Directive
@Directive({
selector: '[dynamicHost]'
})
export class DynamicDirective {
constructor(public viewContainerRef: ViewContainerRef) {}
}
// Container Component
@Component({
selector: 'app-dynamic-container',
template: `
<div class="dynamic-container">
<ng-template dynamicHost></ng-template>
</div>
<button (click)="loadComponent()">Load Dynamic Component</button>
`
})
export class DynamicContainerComponent implements OnInit {
@ViewChild(DynamicDirective, { static: true })
dynamicHost: DynamicDirective;
loadComponent() {
const viewContainerRef = this.dynamicHost.viewContainerRef;
viewContainerRef.clear();
// Create component dynamically
const componentRef = viewContainerRef.createComponent(DynamicContentComponent);
// Pass data to dynamic component
componentRef.instance.data = 'Dynamic data';
}
}
// Dynamic Content Component
@Component({
selector: 'app-dynamic-content',
template: `<h2>{{ data }}</h2>`
})
export class DynamicContentComponent {
@Input() data: string;
}
Dependency Injection & Services
9. What do you understand by Angular Service?
Angular services provide shared functionality across components using dependency injection[39][42]:
@Injectable({ providedIn: 'root' })
export class DataService {
private apiUrl = 'https://api.example.com';
constructor(private http: HttpClient) {}
getData(): Observable<any> {
return this.http.get(`${this.apiUrl}/data`);
}
saveData(data: any): Observable<any> {
return this.http.post(`${this.apiUrl}/data`, data);
}
}
// Using service in component
@Component({
selector: 'app-data'
})
export class DataComponent implements OnInit {
data: any;
constructor(private dataService: DataService) {}
ngOnInit() {
this.dataService.getData().subscribe(
data => this.data = data
);
}
}
11. What is difference between provideIn and providers?
providedIn vs providers configuration[39][45]:
// providedIn: 'root' - Service available application-wide
@Injectable({ providedIn: 'root' })
export class GlobalService {}
// Module-level providers
@NgModule({
providers: [
{ provide: LocalService, useClass: LocalService }
]
})
export class FeatureModule {}
// Component-level providers
@Component({
providers: [
{ provide: ComponentService, useClass: ComponentService }
]
})
export class MyComponent {}
// Different provider configurations
@NgModule({
providers: [
// Class provider
{ provide: MyService, useClass: MyService },
// Value provider
{ provide: API_URL, useValue: 'https://api.example.com' },
// Factory provider
{
provide: ConfigService,
useFactory: (http: HttpClient) => new ConfigService(http),
deps: [HttpClient]
},
// Existing provider
{ provide: Logger, useExisting: ConsoleLogger }
]
})
export class AppModule {}
Change Detection & Performance
20. What do you understand by Change Detection?
Angular's change detection mechanism keeps the view synchronized with the component state[26][29][32]:
@Component({
selector: 'app-change-detection',
template: `
<h2>{{ title }}</h2>
<p>Count: {{ count }}</p>
<button (click)="increment()">Increment</button>
`
})
export class ChangeDetectionComponent {
title = 'Change Detection Demo';
count = 0;
increment() {
this.count++; // Triggers change detection
}
}
Change Detection Triggers:
DOM events (click, keyup, etc.)
HTTP requests
Timers (setTimeout, setInterval)
Promises and Observables
22. What is difference between detectChange and markForCheck
detectChange vs markForCheck for manual change detection control[29][72]:
@Component({
selector: 'app-manual-detection',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ManualDetectionComponent {
constructor(private cdr: ChangeDetectorRef) {}
// markForCheck - marks component and ancestors for checking
updateWithMarkForCheck() {
this.data = newData;
this.cdr.markForCheck(); // Schedules check in next detection cycle
}
// detectChanges - immediately runs change detection
updateWithDetectChanges() {
this.data = newData;
this.cdr.detectChanges(); // Runs change detection immediately
}
}
23. What do you understand by dumb component and smart component?
Smart vs Dumb Component Pattern[69][72]:
// Smart Component (Container)
@Component({
selector: 'app-user-container',
template: `
<app-user-list
[users]="users$ | async"
(userSelected)="onUserSelected($event)">
</app-user-list>
`
})
export class UserContainerComponent {
users$ = this.userService.getUsers();
constructor(private userService: UserService) {}
onUserSelected(user: User) {
this.userService.selectUser(user);
}
}
// Dumb Component (Presentation)
@Component({
selector: 'app-user-list',
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<div *ngFor="let user of users" (click)="selectUser(user)">
{{ user.name }}
</div>
`
})
export class UserListComponent {
@Input() users: User[];
@Output() userSelected = new EventEmitter<User>();
selectUser(user: User) {
this.userSelected.emit(user);
}
}
RxJS & Observables
24. What is difference between promise and observables
Promise vs Observable comparison[68][71]:
// Promise - Single value, eager execution
const promise = new Promise((resolve) => {
console.log('Promise executed immediately');
setTimeout(() => resolve('Promise result'), 1000);
});
promise.then(result => console.log(result));
// Observable - Multiple values, lazy execution
const observable = new Observable(observer => {
console.log('Observable executed only when subscribed');
let count = 0;
const interval = setInterval(() => {
observer.next(`Observable result ${count++}`);
}, 1000);
return () => clearInterval(interval); // Cleanup function
});
const subscription = observable.subscribe(result => console.log(result));
// Unsubscribe after 5 seconds
setTimeout(() => subscription.unsubscribe(), 5000);
25. What is difference between observable and subjects?
Observable vs Subject differences[68][71][77]:
// Observable - Unicast (one-to-one)
const observable = new Observable(observer => {
observer.next(Math.random());
});
// Each subscription gets different values
observable.subscribe(value => console.log('Sub1:', value));
observable.subscribe(value => console.log('Sub2:', value));
// Subject - Multicast (one-to-many)
const subject = new Subject<number>();
// Both subscriptions get same values
subject.subscribe(value => console.log('Sub1:', value));
subject.subscribe(value => console.log('Sub2:', value));
subject.next(Math.random()); // Both subscribers get same value
// BehaviorSubject - Holds current value
const behaviorSubject = new BehaviorSubject<string>('Initial Value');
behaviorSubject.subscribe(value => console.log('Early Sub:', value));
behaviorSubject.next('Updated Value');
behaviorSubject.subscribe(value => console.log('Late Sub:', value)); // Gets current value
27. When we should use BehaviorSubject?
BehaviorSubject Use Cases[68][74][77]:
// State Management Service
@Injectable({ providedIn: 'root' })
export class StateService {
private userState = new BehaviorSubject<User | null>(null);
public user$ = this.userState.asObservable();
// Always provides current user state to new subscribers
setUser(user: User) {
this.userState.next(user);
}
getCurrentUser(): User | null {
return this.userState.getValue(); // Synchronous access
}
}
// Component using BehaviorSubject
@Component({
selector: 'app-user-profile'
})
export class UserProfileComponent implements OnInit {
user$ = this.stateService.user$;
constructor(private stateService: StateService) {}
ngOnInit() {
// Immediately gets current user state, even if set before subscription
this.user$.subscribe(user => {
console.log('Current user:', user);
});
}
}
30. What is async pipe?
Async Pipe automatically subscribes/unsubscribes to observables in templates[99][102][105]:
@Component({
selector: 'app-async-demo',
template: `
<!-- Async pipe with Observable -->
<div *ngFor="let item of items$ | async">{{ item.name }}</div>
<!-- Async pipe with ngIf -->
<div *ngIf="user$ | async as user">
Hello, {{ user.name }}!
</div>
<!-- Loading state -->
<div *ngIf="!(data$ | async); else dataTemplate">
Loading...
</div>
<ng-template #dataTemplate let-data>
<div>{{ data | json }}</div>
</ng-template>
`
})
export class AsyncDemoComponent {
items$ = this.dataService.getItems();
user$ = this.userService.getCurrentUser();
data$ = this.apiService.getData();
constructor(
private dataService: DataService,
private userService: UserService,
private apiService: ApiService
) {}
}
Advanced Angular Concepts
19. What is purpose of @HostBinding
@HostBinding binds properties to the host element[search results indicate this is a directive feature]:
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
@HostBinding('class.highlighted')
get cssClass() {
return this.isHighlighted;
}
@HostBinding('style.backgroundColor')
backgroundColor = 'yellow';
@HostBinding('attr.role')
role = 'button';
private isHighlighted = false;
@HostListener('mouseenter')
onMouseEnter() {
this.isHighlighted = true;
this.backgroundColor = 'lightblue';
}
@HostListener('mouseleave')
onMouseLeave() {
this.isHighlighted = false;
this.backgroundColor = 'yellow';
}
}
21. When we should use onPush?
OnPush Change Detection Strategy should be used for performance optimization[69][72][75]:
@Component({
selector: 'app-optimized',
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<h2>{{ title }}</h2>
<div>{{ data | json }}</div>
`
})
export class OptimizedComponent {
@Input() data: any; // Must be immutable for OnPush to work
title = 'Optimized Component';
constructor(private cdr: ChangeDetectorRef) {}
// Use OnPush when:
// 1. Component receives data via @Input only
// 2. Data is immutable
// 3. Component doesn't perform internal state changes
// 4. Performance is critical
}
// Parent component must pass immutable data
@Component({
template: `<app-optimized [data]="immutableData"></app-optimized>`
})
export class ParentComponent {
immutableData = { name: 'John', age: 30 };
updateData() {
// Create new object reference for OnPush detection
this.immutableData = { ...this.immutableData, age: 31 };
}
}
29. Is it ok to use observable if not why?
Avoid Observable for type safety[search results suggest this is not recommended]:
// ❌ Bad - No type safety
getData(): Observable<any> {
return this.http.get('/api/data');
}
// ✅ Good - Proper typing
interface User {
id: number;
name: string;
email: string;
}
getUser(): Observable<User> {
return this.http.get<User>('/api/user');
}
// ✅ Better - Generic types
getItems<T>(): Observable<T[]> {
return this.http.get<T[]>('/api/items');
}
// Usage with type safety
this.userService.getUser().subscribe(user => {
console.log(user.name); // TypeScript knows 'name' exists
// console.log(user.invalid); // TypeScript error
});
31. What do you understand by union type and intersection type?
TypeScript Types in Angular[search results indicate this is TypeScript knowledge]:
// Union Type - Can be one of several types
type Status = 'loading' | 'success' | 'error';
type StringOrNumber = string | number;
@Component({
selector: 'app-status'
})
export class StatusComponent {
status: Status = 'loading';
value: StringOrNumber = 'hello';
updateStatus(newStatus: Status) {
this.status = newStatus; // Only accepts 'loading', 'success', or 'error'
}
}
// Intersection Type - Combines multiple types
interface User {
name: string;
email: string;
}
interface Admin {
permissions: string[];
level: number;
}
type AdminUser = User & Admin; // Has properties from both interfaces
@Injectable()
export class UserService {
createAdminUser(): AdminUser {
return {
name: 'John Doe',
email: 'john@example.com',
permissions: ['read', 'write'],
level: 5
};
}
}
33. What is purpose of component resolver
Component Resolver (Angular Resolver) pre-fetches data before route activation:
// User Resolver
@Injectable()
export class UserResolver implements Resolve<User> {
constructor(private userService: UserService) {}
resolve(route: ActivatedRouteSnapshot): Observable<User> {
const userId = route.paramMap.get('id');
return this.userService.getUser(userId);
}
}
// Route Configuration
const routes: Routes = [
{
path: 'user/:id',
component: UserComponent,
resolve: { user: UserResolver }
}
];
// Component using resolved data
@Component({
selector: 'app-user',
template: `<h1>{{ user.name }}</h1>`
})
export class UserComponent implements OnInit {
user: User;
constructor(private route: ActivatedRoute) {}
ngOnInit() {
this.user = this.route.snapshot.data['user']; // Pre-resolved data
}
}
Conclusion
This comprehensive guide covers the essential Angular concepts needed for technical interviews. Each topic includes practical code examples and real-world scenarios to demonstrate understanding. Focus on:
Understanding core concepts - Components, services, modules
Mastering component communication - @Input/@Output, services, observables
Performance optimization - Lazy loading, OnPush, change detection
RxJS proficiency - Observables, subjects, async pipe
Advanced patterns - Dynamic components, dependency injection, resolvers
Remember to practice implementing these concepts in real projects to solidify your understanding and be prepared to discuss trade-offs and best practices during interviews.
Subscribe to my newsletter
Read articles from Naveen Chikkamath directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
