DEV Community

Nation Chirara
Nation Chirara

Posted on

Angular Re-usable Components - (@Input) Decorator

Reusable components with Angular

One of the fundamental concepts that I learned about system design is to have/build reusable components. This approach saves time (building and testing the components) and writing boilerplate code.
I am learning Angular and I have found how to build re-usable components in Angular. In Angular, re-usable components are built using two approaches depending on the requirement, a good number of times these are combined.

  1. @Input() – decorator (Part of Component API)
  2. Ng-content directive (Content Projection)

In this article, I am going to show how to use the first approach to achieve component re-usability with @Input() – decorator.

@Input() – decorator - allows you to pass data from parent component to child component. You will not be able to pass HTML. I have taken Bootstrap Card component for this example, and I intend to use this component in multiple places on my site but with different/dynamic headings. Instead of having multiple Cards with different headings, I am going to have one Card. This card is designed in such a way that the consumer/user of the component/card can pass in the heading at the time of calling the component.

import { Component, OnInit, Input } from '@angular/core';
@Component({
  selector: 'app-re-usable-card',
  templateUrl: './re-usable-card.component.html',
  styleUrls: ['./re-usable-card.component.css']
})
export class ReUsableCardComponent implements OnInit {
  @Input() heading: string;
  constructor() { }
  ngOnInit() {
  }
}

@Input() heading: string; This line uses @Input() decorator to mark the property heading as one that can be passed on dynamically, making ReUsableCardComponent re-usable. Do not forget to import Input. Now the template for our re-usable component looks like below:

<div class="card">
    <div class="card-header">
        {{heading}}
    </div>
    <div class="card-body">
        <h5 class="card-title">Special title treatment</h5>
        <p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
        <a href="#" class="btn btn-primary">Go somewhere</a>
    </div>
</div>

{{heading}} - binds the property heading of our component through string interpolation. Whatever that is passed from parent component targeting heading will be rendered inside this div

<div class="card-header">
        //will be put here!
    </div>

The below code shows how we pass data from the parent component to our child component.

<div class="container">
    <div class="row">
        <app-re-usable-card [heading]="'Heading 1'"></app-re-usable-card>
        <app-re-usable-card heading='Heading 2'></app-re-usable-card>
    </div>
</div>

Did you notice that in the card-body div of our component there is HTML content? Is there a way of dynamically injecting/putting that content for re-usability? Yes, that is the job of ng-content, I will look into that in the next article. Thank you for reading, I appreciate comments!

Top comments (0)