Components in Angular

Question 1: What are Components in Angular and why are they important?

Answer: Components are the fundamental building blocks of Angular applications. They are:

  1. Self-contained units of functionality
  2. Consist of a template (HTML), styles (CSS), and logic (TypeScript)
  3. Can be reused across the application
  4. Follow a component-based architecture

Example of a basic component:

@Component({
  selector: 'app-user',
  template: `
    <div class="user-card">
      <h2>{{user.name}}</h2>
      <p>{{user.email}}</p>
    </div>
  `,
  styles: [`
    .user-card {
      padding: 16px;
      border: 1px solid #ccc;
    }
  `]
})
export class UserComponent {
  @Input() user: {name: string; email: string};
}

Question 2: What are the key parts of an Angular Component?

Answer:

// 1. Component Decorator
@Component({
  // Selector for using in HTML
  selector: 'app-product',
  
  // Template (can be inline or separate file)
  templateUrl: './product.component.html',
  
  // Styles (can be inline or separate files)
  styleUrls: ['./product.component.css'],
  
  // Change detection strategy
  changeDetection: ChangeDetectionStrategy.OnPush
})

// 2. Component Class
export class ProductComponent implements OnInit {
  // Properties
  @Input() productId: number;
  @Output() addToCart = new EventEmitter<number>();
  
  // Constructor for dependency injection
  constructor(private productService: ProductService) {}
  
  // Lifecycle hooks
  ngOnInit() {
    this.loadProduct();
  }
  
  // Methods
  addToCartClicked() {
    this.addToCart.emit(this.productId);
  }
}

Question 3: Explain Component Lifecycle Hooks in Angular

Answer:

@Component({...})
export class LifecycleComponent implements 
  OnInit, 
  OnChanges, 
  DoCheck, 
  AfterViewInit,
  AfterViewChecked,
  OnDestroy {
  
  // Called when input properties change
  ngOnChanges(changes: SimpleChanges) {
    console.log('Input changes:', changes);
  }
  
  // Called once after first ngOnChanges
  ngOnInit() {
    console.log('Component initialized');
  }
  
  // Called during every change detection run
  ngDoCheck() {
    console.log('Change detection running');
  }
  
  // Called after view is initialized
  ngAfterViewInit() {
    console.log('View initialized');
  }
  
  // Called after view is checked
  ngAfterViewChecked() {
    console.log('View checked');
  }
  
  // Called before component is destroyed
  ngOnDestroy() {
    console.log('Component being destroyed');
  }
}

Question 4: How do Components communicate with each other?

Answer:

// Parent Component
@Component({
  selector: 'app-parent',
  template: `
    <app-child
      [data]="parentData"
      (dataChange)="onDataChange($event)">
    </app-child>
  `
})
class ParentComponent {
  parentData = 'Hello';
  
  onDataChange(newData: string) {
    console.log('Child changed data:', newData);
  }
}

// Child Component
@Component({
  selector: 'app-child'
})
class ChildComponent {
  @Input() data: string;
  @Output() dataChange = new EventEmitter<string>();
  
  updateData(newValue: string) {
    this.dataChange.emit(newValue);
  }
}

Question 5: What are Component Styles and View Encapsulation?

Answer:

@Component({
  selector: 'app-styled',
  template: `
    <div class="container">
      <h1>{{title}}</h1>
    </div>
  `,
  styles: [`
    .container { 
      padding: 20px;
    }
    h1 { 
      color: blue;
    }
  `],
  // View Encapsulation options
  encapsulation: ViewEncapsulation.Emulated // Default
  // Other options:
  // ViewEncapsulation.None
  // ViewEncapsulation.ShadowDom
})

Common Interview Follow-up Questions:

  1. Q: What’s the difference between smart and presentational components? A: Smart components manage data and business logic, while presentational components focus on UI and receive data via inputs.

  2. Q: How do you optimize component performance? A: Use OnPush change detection, implement trackBy with ngFor, use pure pipes, and lazy load components when possible.

    @Component({
      changeDetection: ChangeDetectionStrategy.OnPush
    })
    class OptimizedComponent {
      trackByFn(index: number, item: any): number {
        return item.id;
      }
    }
  3. Q: What are content projection and ng-content? A: They allow components to receive and display content from their parent:

    @Component({
      selector: 'app-card',
      template: `
        <div class="card">
          <div class="header">
            <ng-content select="[header]"></ng-content>
          </div>
          <div class="body">
            <ng-content></ng-content>
          </div>
        </div>
      `
    })
  4. Q: How do you handle errors in components? A: Use error boundaries, try-catch blocks, and error handlers:

    @Component({
      template: `
        @if (error) {
          <error-display [error]="error" />
        } @else {
          <ng-content></ng-content>
        }
      `
    })
    class ErrorBoundaryComponent implements ErrorHandler {
      error: any = null;
      
      handleError(error: any) {
        this.error = error;
      }
    }

Test Your Knowledge

Take a quick quiz to test your understanding of this topic.

Test Your Angular Knowledge

Ready to put your skills to the test? Take our interactive Angular quiz and get instant feedback on your answers.