This article is for versions of Angular 2, Angular 4 and later.

Angular components are a fantastic way to break up our web apps into small easy to understand pieces of UI code. Sometimes in certain apps we have drastic layout differences for the same data being displayed. A example could be differences between mobile and desktop layouts. Sometimes it could be displaying our data in different formats such as a list view vs a table view.

In these instances many times our component is a presentation component displaying this data and we have the same Inputs and Output data. In these cases it would be really helpful to be able to swap the templates when displaying the data in different formats. In this post we are going to use Angular Component Inheritance to derive two sub components to display some data. One component will be a list view and another a table view.

Angular Component Inheritance

Base Component Class

Overall I do not recommend using Component Inheritance but rather use composition to mix and match multiple components together. In this particular use case Component Inheritance is rather helpful when our templates have drastic differences in markup but display the same data.

First we need to define our base class that contains all of the logic we want to share.



import { Component, Input, Output, EventEmitter } from '@angular/core';
import { Employee } from './interfaces';

@Component({
  selector: 'app-employee',
  template: ''
})
export class EmployeeComponent {
  @Input() employees: Employee[] = [];
  @Output() select = new EventEmitter();

  heading = 'Employees';

  selectEmployee(employee: Employee) {
    this.select.emit(employee);
  }
}


Our base employee component has one input and one output. It takes in a list of employee objects to display and emits an event to the parent component when a employee is selected. Notice closely that we don’t have a template. This is because we are going to extend this component into a employee-list.component and employee-table.component.

Component Inheritance



import { Component } from '@angular/core';
import { EmployeeComponent } from './employee.component';

@Component({
  selector: 'app-employee-list',
  template: `
    <h1>{{heading}}</h1>
    <ul>
      <li *ngFor="let employee of employees">
        {{employee.firstName}} {{employee.lastName}} <br>
        {{employee.email}} <br>
        <button (click)="selectEmployee(employee)">Select</button>
      </li>
    </ul>
  `
})
export class EmployeeListComponent extends EmployeeComponent {
  heading = 'Employee List';
}



Above is our component that inherits our base component class. We do this by extending the class with this line of code EmployeeListComponent extends EmployeeComponent. We inherit all the input and outputs of the base class. In our list component we override the decorator with a list template and override the heading property. Now we can reuse all of the base class logic with a different template. Below is our other component the employee-table.component.



import { Component } from '@angular/core';
import { EmployeeComponent } from './employee.component';

@Component({
  selector: 'app-employee-table',
  template: `
    <h1>{{heading}}</h1>
    <table>
      <tr>
        <td>First Name</td>
        <td>Last Name</td>
        <td>Email</td>
      </tr>
      <tr *ngFor="let employee of employees">
        <td>{{employee.firstName}}</td>
        <td>{{employee.lastName}}</td>
        <td>{{employee.email}}</td>
        <td><button (click)="selectEmployee(employee)">Select</button></td>
      </tr>
    </table>
  `
})
export class EmployeeTableComponent extends EmployeeComponent { }



We can see above that we can share our base component logic and have drastically different template that share the same behavior.



<app-employee-list 
  [employees]="employees"
  (select)="selectEmployee($event)"></app-employee-list>
  
<app-employee-table
  [employees]="employees"
  (select)="selectEmployee($event)"></app-employee-table>


In the code above we can see both inherited child components now share the same public API.

While composition is the preferred way to use components using component inheritance can provide benefits in certain use cases. This is especially useful of UI kits and component libraries. Check out the running demo below!

Demo