Dynamic Tooltip with Angular Pipe: Performance Orientation
Dynamic Tooltip with Angular Pipe
Most of the time we have a requirement to transform our data into a different style or format from what we received from API services.
✋ A pipe takes in data as input and transforms it into a desired output.
Angular provides many Built-In Pipes as well as we can also create custom pipes as per our requirements.
import { Pipe, PipeTransform } from '@angular/core';
In this Blog we will learn use of pipes with Tool tip.
Why need to implement a tooltip with Pipe ❓
✅ Simple Message in Tooltip
If we have to apply a simple message in the tooltip like ‘Name is required’, so we can directly append the tooltip in HTML with a form control.
✅ Conditional Tooltip
Sometimes we have to display tooltips with various checks. Examples of User name fields:
- Show the tooltip If the Field is blank
- If field’s value is less than 6 – show the tooltip message for length.
- If the username is found duplicate show a tooltip message for that.
▶️ If we do this in HTML, it will have various if else conditions checks.
▶️ We can call a method from the class file where we can put all cases and can return messages from there.
TS File ▶
getTooltip(): string {
const field = this.form.controls.userName;
// put our cases
return message;
}
HTML ▶
<input type="text" formControlName = "userName" [tooltip] = "getTooltip()" />
In the above method, the problem is for each change detection this method will be called and that impacts page performance. So to overcome we can use pure pipes. Pure Pipes only execute when that particular field value is changed.
Let’s start coding :

HTML template
<div class="card m-3">
<h5 class="card-header">Implementation of Tooltip using Pipe</h5>
<div class="card-body">
<form [formGroup]="registerForm" (ngSubmit)="onSubmit()">
<div class="form-row">
<div class="form-group col">
<label>First Name</label>
<input type="text" formControlName="firstName" class="form-control" required
[ngClass]="{ 'is-invalid': submitted && f.firstName.errors }"
[title] ="f.firstName.errors | regTooltip : 'firstName'" />
</div>
<div class="form-group col">
<label>Email</label>
<input type="text" formControlName="email" class="form-control" required
[ngClass]="{ 'is-invalid': submitted && f.email.errors }"
[title] ="registerForm.controls.email.errors | regTooltip : 'email'" />
</div>
</div>
<div class="form-group">
</div>
<div class="form-row">
<div class="form-group col">
<label>Password</label>
<input type="password" formControlName="password" class="form-control"
[ngClass]="{ 'is-invalid': submitted && f.password.errors }"
[title] ="f.password.errors | regTooltip : 'password'" />
</div>
<div class="form-group col">
<label>Confirm Password</label>
<input type="password" formControlName="confirmPassword" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.confirmPassword.errors }" />
<div *ngIf="submitted && f.confirmPassword.errors" class="invalid-feedback">
<div *ngIf="f.confirmPassword.errors.required">Confirm Password is required</div>
<div *ngIf="f.confirmPassword.errors.mustMatch">Passwords must match</div>
</div>
</div>
</div>
<div class="form-group form-check">
<input type="checkbox" formControlName="acceptTerms" id="acceptTerms" class="form-check-input" [ngClass]="{ 'is-invalid': submitted && f.acceptTerms.errors }" />
<label for="acceptTerms" class="form-check-label">Accept Terms & Conditions</label>
<div *ngIf="submitted && f.acceptTerms.errors" class="invalid-feedback">Accept Ts & Cs is required</div>
</div>
<div class="text-center">
<button class="btn btn-primary mr-1">Submit</button>
<button class="btn btn-secondary" type="reset" (click)="onReset()">Reset</button>
</div>
</form>
</div>
</div>
TS File
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'app-add-todo',
templateUrl: './add-todo.component.html',
styleUrls: ['./add-todo.component.scss']
})
export class AddTodoComponent implements OnInit {
registerForm: FormGroup;
submitted = false;
constructor(private formBuilder: FormBuilder) { }
ngOnInit() {
this.registerForm = this.formBuilder.group({
firstName: ['', Validators.required],
email: ['', [Validators.required, Validators.email]],
password: ['', [Validators.required, Validators.minLength(6)]],
confirmPassword: ['', Validators.required],
acceptTerms: [false, Validators.requiredTrue]
});
}
// convenience getter for easy access to form fields
get f() { return this.registerForm.controls; }
onSubmit() {
this.submitted = true;
}
onReset() {
this.submitted = false;
this.registerForm.reset();
}
}
RegisterFormTooltipPipe (register-form-tooltip.pipe.ts)
import { Pipe, PipeTransform } from '@angular/core';
import { ValidationErrors } from '@angular/forms';
@Pipe({
name: 'regTooltip'
})
export class RegisterFormTooltipPipe implements PipeTransform {
transform(errors: ValidationErrors, control: string): string {
let message = '';
switch (errors && control) {
case 'firstName':
message = 'Name is required';
break;
case 'email':
if (errors.required) {
message = 'Email is required';
} else if (errors.email) {
message = 'Email must be a valid email address';
}
break;
case 'password':
if (errors.required) {
message = 'Password is required';
} else if (errors.minlength) {
message = 'Password must be at least 6 characters'
}
break;
}
console.log('error on : ', control, errors);
return message;
}
}
App Module file
import { RegisterFormTooltipPipe } from './registration-form-tooltip.pipe';
declarations: [
RegisterFormTooltipPipe
],
index.html scripts (Here we have used Bootstrap)
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
FINAL UI

UNIT TEST CASES OF ANGULAR PIPE
import { RegisterFormTooltipPipe } from "./registration-form-tooltip.pipe"; describe('RegisterFormTooltipPipe', () => { let pipe; it('create an instance', () => { expect(pipe).toBeTruthy(); }); beforeEach(() => { pipe = new RegisterFormTooltipPipe(); }); describe('should run transform method', () => { it('firstName should be required ', () => { const message = pipe.transform({ required: true }, 'firstName'); expect(message).toBeDefined(); }); it('password should be required ', () => { const message = pipe.transform({ required: true }, 'password'); expect(message).toBeDefined(); }); }); });
Visit Bootstrap blog:
https://getbootstrap.com/docs/4.5/getting-started/introduction/
- Angular Interview Questions & Answers 2021 – Part 3 – JS Mount
- Why Angular is a Preferred Choice for Developers? Top Features
- Angular Interview Questions & Answers You should know Part 2
- Web Application Security Best Practices | Top Tips to Secure Angular App
- NgRx Top Interview Questions and Answers You should know
- Tips to Boost Angular App Performance | Web page Speed Optimization
- Angular NgModule, AOT, and DI, and EntryComponents with example
- Angular Dependency Injection Provider and Types of Provider
- Rx JS Top Operators with examples | Rx JS interview questions
- What’s new in Angular 9 | Top updates in Angular 9 By JS mount
- What’s new in Angular 8 | Angular 8 Latest Feature By JS mount
- Prime NG Row Group with Subheader and Totals Row
- How to implement Reactive Form with Prime NG table
- Angular Unit Testing Spy, Router, Fake Async, tick, & Subscribe
- Angular Auto Tab Directive : Auto focus on next field
- VS Code Useful Extensions for Web Development
- Angular HTTP Request Testing with HttpClientTestingModule & HttpTestingController
- Dynamic Tooltip with Angular Pipe: Performance Orientation
- Best Practices for Writing Angular Apps | Angular Guidelines
- Angular Interview Question & Answers for Experienced – Part 1
- Angular Custom directive to match password and confirm password
dynamic tooltip using pipe angular, angular tooltip dynamic, Angular Pipe to display tooltip, how to make dynamic tooltip in angular, Toolip in angular using pipe