Build a Reusable Button Component with Angular

Build a Reusable Button Component with Angular

Build a Reusable Button Component with Angular.We have seen how to build a reusable component that can be used in many different situations. Obviously, this here is a simplified case, but it shows the approach a developer should use for this kind of challenge really well.

One of the first concerns of a good web developer is writing clean code and avoiding repetition. This strategy becomes a necessity when developing large, scalable applications that could be expanded with new features in the future.

Reusable components can make the difference between a successful project and one with high technical debt.

In this article, we will build together a reusable, customizable button component that will be able to display text buttons or image buttons according to the provided configuration.

Step 1. Base Structure

First of all, when thinking about the structure of a reusable component, we need to take into consideration all the uses we want to make of it.

In the case of a reusable button, we want to create a presentational (or dumb) component that will receive the correct configuration from its parent component.

import { Component, OnInit, Input } from '@angular/core';

@Component({
  selector: 'app-button',
  templateUrl: './button.component.html',
  styleUrls: ['./button.component.scss']
})
export class ButtonComponent implements OnInit {
  @Input() buttonConfig: any;
  constructor() {}

  ngOnInit() {}
}

button.component.ts

The object buttonConfigwill contain the styling and additional information about which kind of button we want to render: if we want a text button, the buttonConfigwill contain a textproperty; otherwise, if we want to render an image button, the configurations will specify an image source.

The HTML code will contain two different templates, one for text buttons and one for the image buttons.

Using the ngTemplateOutletpattern, we can specify when to render each one.

In this case, if the configurations contain the textproperty, the #text template will be rendered; if there’s no text property, the rendered template will be#image.

<ng-container *ngTemplateOutlet="buttonConfig['text'] ? text : image">
</ng-container>

<!-- Text Button -->
<ng-template #text>

</ng-template>

<!-- Image Button -->
<ng-template #image>

</ng-template

button.component.html

Step 2. Buttons Markup

Now that the templates are ready, we can fill them with the code for the buttons.

As you can see, the text button will display the property buttonConfig.text through interpolation. The image button is just a clickable image that will have the property buttonConfig.srcas its image source.

<ng-container *ngTemplateOutlet="buttonConfig['text'] ? text : image">
</ng-container>

<!-- Text Button -->
<ng-template #text>
  <button type="button"
          [ngStyle]="buttonConfig.styles"
          (click)="onTextBtnClick()">
    {{ buttonConfig.text | uppercase}}
  </button>
</ng-template>

<!-- Image Button -->
<ng-template #image>
  <img alt="image button"
       [src]="buttonConfig.src"
       [ngStyle]="buttonConfig.styles"
       (click)="onImgBtnClick()">
</ng-template>

button.component.html

Step 3. Configuration

With the button component ready to receive its configuration as input, we can define our custom styles in the parent component.

In this case, I have chosen to create a textBtnConfigobject and an imgBtnConfig to show you how I’ll use the button component to render two different instances at the same time and with different configurations.

It’s important to notice that since we are declaring the CSS styling in a TypeScript object, we’ll need to use the camelCase format when naming the properties! Hence ‘background-color’becomes ‘backgroundColor’, etc.

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  message = 'Click on a button';
  textBtnConfig = {
    styles: {
      position: 'relative',
      width: '150px',
      height: '60px',
      backgroundColor: '#f92672',
      color: '#fff',
      fontFamily: 'sans-serif',
      fontSize: '20px',
      borderRadius: '10px',
      marginTop: '30px'
    },
    text: 'Click Here'
  };

  imgBtnConfig = {
    styles: {
      position: 'relative',
      width: '100px',
      height: '100px'
    },
    src: './assets/conversation.png'
  };

  onClickEventReceived(event: string) {
    this.message = event;
  }
}

app.component.ts

Step 4. Rendering

Finally, we can use the button component to instantiate two buttons in the parent component:

<section>
  <h1>DIFFERENT BUTTONS, SAME COMPONENT!</h1>
  <span>{{message}}</span>
  <div class="btns-container">
    <app-button [buttonConfig]="textBtnConfig"
                (textBtnClickEmt)="onClickEventReceived($event)"></app-button>
    <app-button [buttonConfig]="imgBtnConfig"
                (imgBtnClickEmt)="onClickEventReceived($event)"></app-button>
  </div>
  <div class="copyright">
    <span>Code by Alessia Amitrano.</span>
    <span>
      Icons made by <a href="https://www.flaticon.com/authors/freepik"
         title="Freepik">Freepik</a> from <a href="https://www.flaticon.com/"
         title="Flaticon">www.flaticon.com</a></span>
  </div>
</section>

app.component.html

Once the app is served, the result will be similar to this:

This is image title

Conclusion

We have seen how to build a reusable component that can be used in many different situations. Obviously, this here is a simplified case, but it shows the approach a developer should use for this kind of challenge really well.

Just think about how much code we would have written without a reusable component!

Moreover, reusable components allow implementing new features for every instance of the component with the minimum amount of changes to the code. If we wanted to add a new method, it would be available for every button, no matter if it’s a text or an image button.

You can find the full example implemented by me in this GitHub Repo.

Icons made by Freepik from www.flaticon.com

angular javascript programming

What's new in Bootstrap 5 and when Bootstrap 5 release date?

How to Build Progressive Web Apps (PWA) using Angular 9

What is new features in Javascript ES2020 ECMAScript 2020

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

Random Password Generator Online

HTML Color Picker online | HEX Color Picker | RGB Color Picker

Basics of Angular: Part-1

What is Angular? What it does? How we implement it in a project? So, here are some basics of angular to let you learn more about angular. Angular is a Typesc

How to Build an Angular Application with Angular CLI

How to set up the Angular CLI and generate a Trivial App

Angular 9 App From Scratch - Build Angular 9 Memes Generator App 😜😜

Angular 9 App From Scratch In this video we gonna be looking at how to create an Angular 9 Memes Generator App From Scratch, we will be looking at, 👉👉 How to...

How to start writing less error-prone code in JavaScript

How to start writing less error-prone code in JavaScript - Everything in JavaScript is an object!’. We said that this assertion is false. Many things in JavaScript can behave like an object, but that doesn’t mean it’s the object. We can say we have three types of objects (objects, functions and arrays) in JavaScript.

The essential JavaScript concepts that you should understand

The essential JavaScript concepts that you should understand - For successful developing and to pass a work interview