How to inherit a component in Angular and reuse its template

Krishnan Mudaliar
Acute Angular
Published in
3 min readAug 2, 2020
Photo Courtesy: https://live.staticflickr.com/5481/14581168505_1161f27596_b.jpg

TL;DR. Point templateUrl of your ChildComponent to the Base component’s template file. Similarly, for the CSS file. You may override Base component’s CSS by adding multiple CSS files too. Here’s an example code.

@Component({
selector: 'eg-child',
templateUrl: './../base/base.component.html',
styleUrls: [
'./../base/base.component.scss',
'./child.component.scss',
],
})
export class ChildComponent extends BaseComponent {
// ...
}

A proper explanation

Class inheritance is pretty straightforward, even for an Angular Component class. You create a BaseComponent class, and do ChildComponent extends BaseComponent. However, the template is not inherited into ChildComponent as it is part of the @Decorator. So, you still have to set templateUrl: 'child.component.html' and define its HTML again. In most cases, this may be fine because your ChildComponent’s Template View may be different from that of the Base. But, what if it wasn’t; what if you wanted to simply reuse base.component.html?

Usually, we end up making a compromise and do something like this.

@Component({
selector: 'eg-child',
template: `<eg-base></eg-base>`,
})
export class ChildComponent {
// ...
}

This is a compromise because this is a Composition of objects rather than Inheritance. Also, it may not be clear at the beginning, but it paves the path for further design compromises in future, OR you are not able to leverage the powers of object-oriented programming.

Problem 1: Accessing base component’s properties and methods

Sure, you can and access the base component and its properties and methods using @ViewChild(BaseComponent) baseComponent;. But, to do so, you have to expose all of those properties and methods as public.

Problem 2: Overriding base component’s properties and methods

You cannot solve this problem. Hence, you will end up creating @Input and @Output properties in your BaseComponent to customize the Base’s behaviors.

A cleaner solution

First, of course, inherit your ChildComponent from BaseComponent. Next, point templateUrl of your ChildComponent to the Base’s template file. Similarly, for the CSS file too.

Note: URL path to base.component.html or .scss needs to be relative to your current ChildComponent’s path. (Would be awesome if someone can tell me how to make it relative to the Angular app root, or node_modules. I know this is possible.)

Pro-Tip: You can override the Base’s CSS by adding multiple CSS files to styleUrls. This is useful when you need to have a different look and feel for your child component. Here is a detailed code example.

Full code example of component inheritance and template reuse

In this example, you can see the following behaviors and benefits.

  1. Child points to the template of the Base.
  2. Child points to the style of the Base and its own style.
  3. Base component contains the logic for API-data retrieval and Form-Building functionalities that are automatically available in the Child now.
  4. Protected properties and functions, like entityType, initFormGroup, etc., are accessible only in inherited class. No more unnecessary public properties and functions.
  5. In the Child component, the Base’s entityType is set in the constructor.
  6. Base’s initFormGroup is overridden in the Child.

The above example could be tweaked further to make the base class generic, i.e. EntityFormComponent<T>, thereby be able to define strongly-typed properties (like SomeEntityService<T>) instead of any.

Hope you found the information in this article useful. Open for comments and suggestions.

--

--

Acute Angular
Acute Angular

Published in Acute Angular

Yet another Angular blog — but let’s focus on the minute details first

Krishnan Mudaliar
Krishnan Mudaliar

Written by Krishnan Mudaliar

Loves the web • DIY • DRY • ASP.NET • JavaScript • Angular • NodeJS (i/bitsy) • Believer of great UX