How To Build Re-Usable Component In Angular With component Interaction-Sagar-Jaybhay

How to build re-usable component with Interaction in angular by sagar jaybhay

In order to make component re-usable, you need to add input and output properties. We use input properties to pass a state or give the input to component and use output properties to raise the event.

So because of input and output properties, our component becomes a public API.

Input Properties:

How to make the property as Input Property?

@Input Is decorator for marking field and properties as input properties.

@Input() is clicked:boolean;

This is code for making the property as input field and when it is used refer to referring component you need to use below code we use this app component.

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'hello-sagar-jaybhay';
  post={
   isClicked:true
  } 
}

Now we use this as reusable component of favorites and in app.component.html template write below code.

<rating [isClicked]="post.isClicked"></rating>

Now we will see the Favorite component itself.

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

@Component({
    selector:'rating',
    template:`
    <span>I m in rating Component</span>
    <div class="container">
    <button (click)="onClickStar()">
    <span>
    <i class="{{isClicked==true?'fa fa-star':'fa fa-star-o'}}"></i>
  </span>
  </button>
    </div>
    `
    
})
export class Rating implements OnInit
{
    ngOnInit(): void {
        console.log('i m in OnInit => '+this.isClicked);
    }
    cssClass="fa fa-star-o";

   @Input() isClicked:boolean;

onClickStar()
{
       this.isClicked=!this.isClicked;

}

}
How To Build Re-Usable Component In Angular With component Interaction-Sagar-Jaybhay

By marking property or field in class it will make our property input property.

Second Way to make the property as Input property:

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

@Component({
    selector:'rating',
    template:`
    <span>I m in rating Component</span>
    <div class="container">
    <button (click)="onClickStar()">
    <span>
    <i class="{{isClicked==true?'fa fa-star':'fa fa-star-o'}}"></i>
  </span>
  </button>
    </div>
    `,
    inputs:['isClicked']
    
})
export class Rating implements OnInit
{
    ngOnInit(): void {
        console.log('i m in OnInit => '+this.isClicked);
    }
    cssClass="fa fa-star-o";

isClicked:boolean;

onClickStar()
{
       this.isClicked=!this.isClicked;

}

}
How To Build Re-Usable Component In Angular With component Interaction-Sagar-Jaybhay

In the above approach, we don’t Import Input decorator from the angular core rather than in Component decorator inbuild field input we use that but there is one drawback in this if we somehow our name is changed then the application fails.

How to alias to input property or nickname?

@Input('is-Favourite') isClicked:boolean;

And in-app component where we refer this component use below code.

<rating [is-Favourite]="post.isClicked"></rating>

In this approach, one benefit is that If somehow name changes or we change our naming convention by the use of alias our application will work.

Output Properties:

In this main thing is that we handle the reusable component event in the host component and how to handle this is by using the Output properties in angular which is also kind of decorator.

Now in our application rating component, we have added in app.component which is our host component.

How To Build Re-Usable Component In Angular With component Interaction-Sagar-Jaybhay
import { Component, Input, OnInit, Output,EventEmitter } from "@angular/core";

@Component({
    selector:'rating',
    template:`
    <span>I m in rating Component</span>
    <div class="container">
    <button (click)="onClickStar()">
    <span>
    <i class="{{isClicked==true?'fa fa-star':'fa fa-star-o'}}"></i>
  </span>
  </button>
    </div>
    `    
})
export class Rating implements OnInit
{
    ngOnInit(): void {
        console.log('i m in OnInit => '+this.isClicked);
    }
    cssClass="fa fa-star-o";
   @Input('is-Favourite') isClicked:boolean;
   @Output() change=new EventEmitter();
   
   onClickStar()
    {
       this.isClicked=!this.isClicked;
       this.change.emit();
    }
}

This is our rating component which we make re-usable.

Below code is in the app component.

<rating [is-Favourite]="post.isClicked" (change)="onRatingChanged()"></rating>

In the above example, you will see that we use change is Output property and which we initialized to EventEmitter and this is used to emit the event. In this we handle click event in rating means self component also but when we want to handle outside that component we use emit() method. The name of Output property we need to use same in app.component.html as you can see in above code where we add onRatingChanged event added.

Below is the code in app.component.html

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'hello-sagar-jaybhay';
  post={
   isClicked:true
  }

  onRatingChanged(){
    console.log('i am in app component event emitter function');
  }
 
}
How To Build Re-Usable Component In Angular With component Interaction-Sagar-Jaybhay

In this case, we have app component is our subscriber of that event.

So Next question is How I pass data when raising that event?

In the emit method we can pass anything means from simple datatype to complex object. Below is the example of a simple Boolean value.

How To Build Re-Usable Component In Angular With component Interaction-Sagar-Jaybhay

Now we want to pass a complex object

How To Build Re-Usable Component In Angular With component Interaction-Sagar-Jaybhay

For rating component code is below

import { Component, Input, OnInit, Output,EventEmitter } from "@angular/core";

@Component({
    selector:'rating',
    template:`
    <span>I m in rating Component</span>
    <div class="container">
    <button (click)="onClickStar()">
    <span>
    <i class="{{isClicked==true?'fa fa-star':'fa fa-star-o'}}"></i>
  </span>
  </button>
    </div>
    `    
})
export class Rating implements OnInit
{
    ngOnInit(): void {
        console.log('i m in OnInit => '+this.isClicked);
    }
    cssClass="fa fa-star-o";
   @Input('is-Favourite') isClicked:boolean;
   @Output() change=new EventEmitter();
   
   onClickStar()
    {
       this.isClicked=!this.isClicked;
       var newObject={
           needtopass:"demo string",
           numb:12,
           boolval:false
       }
       this.change.emit(JSON.stringify(newObject));
    }
}

For Host, UI template code is below

<!--The content below is only a placeholder and can be replaced.-->
<h1>Angular Application</h1>

<!-- <course></course> -->
<!-- <course></course> -->
<!-- <myImage></myImage> -->

<!-- <blog></blog> -->

<rating [is-Favourite]="post.isClicked" 
(change)="onRatingChanged($event)"></rating>
<router-outlet></router-outlet>

And for the host class file where we write the code for this

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'hello-sagar-jaybhay';
  post={
   isClicked:true
  }

  onRatingChanged(object){
    console.log("i am in app "+
    +"component event emitter function  "+
    " ==> "+object);
  }
 
}

But in the above case we didn’t get intellisense so for that we need to declare one interface and pass the data with that.

How To Build Re-Usable Component In Angular With component Interaction-Sagar-Jaybhay

Code for that where we pass the declared interface and function parameter as interface type and we check the type of that in app.component.  For demo purpose, I have added the interface in app.component.ts file but it will be declared in another file and we need to import this.

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

interface PassedData{
  needtopass:string,
  numb:number,
  boolval:boolean;
}

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'hello-sagar-jaybhay';
  post={
   isClicked:true
  }

  onRatingChanged(object:PassedData){
    console.log("i am in app "+
    +"component event emitter function  "+
    " ==> "+object.boolval+" "+object. );
  }
 
}

In output property, we also use an alias for being the contract stable.

How To Build Re-Usable Component In Angular With component Interaction-Sagar-Jaybhay

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *