import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { TitleCasePipe } from '@angular/common';
import { TitlecaseDirective } from './titleCase.directive';
@NgModule({
declarations: [
AppComponent,
TitlecaseDirective
],
imports: [
BrowserModule,
BrowserAnimationsModule,
FormsModule
],
providers: [TitleCasePipe], // provide titlecase pipe to use it in directive.ts and component.ts
bootstrap: [AppComponent]
})
export class AppModule { }
How to Convert NgModel / FormControl Input Text to Title Case using Angular Directive and Angular Pipe

You can easily convert the text in input fields to title case using Angular TitleCase Pipe along with the power of Angular Directives. In this tutorial, I am going to show you how to create a reusable TitleCase directive, which converts the text entered by the user to Title Case.
The first section of this post will show you how to make use of Angular built-in TitleCase
pipe. The second section of this post will teach you how to write our own logic to convert the text to title case.
Create TitleCase Directive
Create a new TitleCase directive using the following command
ng generate directive title-case
Add the following HTML code in your app.component.html file.
<input type="text" appTitleCase [(ngModel)]="firstname" name="firstname"/>
We have added the appTitleCase
selector to the input field which is our title case directive.
1. Using Angular TitleCase Pipe
From Angular 4, Angular has a built-in pipe for Title Case called TitleCase. You can use it to transform data in your template as follows:
<h1>{{ hello world | titlecase }}</h2>
<!-- output is expected to be "Hello World" -->
It’s very easy to transform the data in your HTML template into title case using the TitleCase
pipe. But, you can’t use this method to transform the data in your input fields. In other words, you can’t write something like this: [ngModel]="modelName | titlecase"
or [formControl]="controlName | titlecase"
To solve this problem, we are going to use the TitleCase pipe inside our newly created TitleCase
Directive.
How to Access Angular Pipe Inside Angular Directive
To access the pipe inside the angular directive, you should first provide the pipe in the providers
array of your module. You can import the built-in TitleCasePipe
from @angular/common
package.
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { TitleCasePipe } from '@angular/common';
import { TitlecaseDirective } from './titleCase.directive';
@NgModule({
declarations: [
AppComponent,
TitlecaseDirective
],
imports: [
BrowserModule,
BrowserAnimationsModule,
FormsModule
],
providers: [TitleCasePipe], // provide titlecase pipe to use it in directive.ts and component.ts
bootstrap: [AppComponent]
})
export class AppPatientModule { }
Now you can import TitleCasePipe
into the constructor
of your newly created TitleCaseDirective
. You should also import NgControl
class to the constructor.
What is NgControl?
NgControl
is the base class for all the form controls. In our case, Once we transformed the data to title case we will update the value of the form control using NgControl.valueAccessor
. The valueAccessor
has a method called writeValue
which is used to update the value of the form control.
import { Directive, HostListener } from '@angular/core';
import { NgControl } from '@angular/forms';
import { TitleCasePipe } from '@angular/common';
@Directive({
selector: '[appTitleCase]'
})
export class TitlecaseDirective {
constructor(
public ngControl: NgControl,
public titleCase: TitleCasePipe
) { }
}
Listen For Input Change
To listen for the input change in our directive, we should use @HostListener('ngModelChange', ['$event'])
. The ngModelChange
triggers whenever the user changes the input field text (ngModel/formControl)
.
@HostListener('ngModelChange', ['$event'])
onInputChange(value) {
// whenever user types something in the input field, this function triggers.
}
Convert To Title Case using TitleCasePipe
The TitleCasePipe
has a transform method which has the logic to convert the data to title case. We assign the returned value to a variable called titleCaseStr
. Then, we should update the value of the form control using the writeValue
method of valueAccessor
.
@HostListener('ngModelChange', ['$event'])
onInputChange(value) {
const titleCaseStr = this.titleCase.transform(value);
this.ngControl.valueAccessor.writeValue(titleCaseStr);
}
2. Write Your Own Title Case Conversion Logic
If you are like me, to dig deeper into the logic and understand what happens under the hood rather than just using the API. This section is for you.
There are multiple ways to convert the string to title case in JavaScript. In this section, I will teach you three ways of title case conversion.
- Using for…of loop
- Using the Array map method
- Using the Array reduce method
Convert Text to Title Case Using for…of loop
- Declare a variable called
arrStr
. - Convert the incoming value to lower case and split the string into an array. Assign the returned array to the
arrStr
variable. - Declare a variable called
titleCaseArr
with a default value as an array. - Write a
for of
loop, access the first character of the string usingcharAt
method and convert the first letter to uppercase. - Select the remaining characters of the string using
slice(1)
method. - Concatenate the string and push it to the
titleCaseArr
array. - Convert the
titleCaseArr
to string using the join method and update the form field usingwriteValue
method.
@HostListener('ngModelChange', ['$event'])
onInputChange(value) {
const arrStr = value.toLowerCase().split(' ');
const titleCaseArr: Array<any> = [];
for (const str of arrStr) {
titleCaseArr.push(str.charAt(0).toUpperCase() + str.slice(1));
}
this.ngControl.valueAccessor.writeValue(titleCaseArr.join(' '));
}
Convert text to Title Case using Array Map method
- Declare a variable called
arrStr
. - Convert the incoming value to lower case and split the string into an array. Assign the returned array to the
arrStr
variable - Declare a variable called
titleCaseStr
. - Use the map method in
arrStr
, access the first character of the string usingcharAt
method and convert the first letter to uppercase. - Select the remaining characters of the string using
slice(1)
method. - Concatenate the first letter and remaining letters and return it.
- Chain the
join
method after themap
method to convert the array to string. - Update the form field using
writeValue
method.
@HostListener('ngModelChange', ['$event'])
onInputChange(value) {
const arrStr = value.toLowerCase().split(' ');
const titleCaseStr = arrStr.map((str) => (str.charAt(0).toUpperCase() + str.slice(1))).join(' ');
this.ngControl.valueAccessor.writeValue(titleCaseStr);
}
Convert text to Title Case using Array Reduce method
- Declare a variable called
arrStr
. - Convert the incoming value to lower case and split the string into an array. Assign the returned array to the
arrStr
variable - Declare a variable called
titleCaseStr
. - Use the reduce method in
arrStr
. - Declare a variable inside the reduce method called
spaceBetweenWords
, If the first parameter of the reduce method which is the accumulated value calledaccumulatedStr
is not equal to an empty string, then we assign space to thespaceBetweenWords
- Access the first character of the string using
charAt
method and convert the first letter to uppercase. - Select the remaining characters of the string using
slice(1)
method. - Concatenate the first letter and remaining letters and return it.
- Update the form field using
writeValue
method.
@HostListener('ngModelChange', ['$event'])
onInputChange(value) {
const arrStr = value.toLowerCase().split(' ');
const titleCaseStr = arrStr.reduce((accumulatedStr, currentStr) => {
const spaceBetweenWords = (accumulatedStr ? ' ' : '');
return accumulatedStr += spaceBetweenWords + (currentStr.charAt(0).toUpperCase() + currentStr.slice(1));
}, '');
this.ngControl.valueAccessor.writeValue(titleCaseStr);
}
FULL CODE EXAMPLE FOR ANGULAR TITLE CASE DIRECTIVE
import { Directive, HostListener } from '@angular/core';
import { NgControl } from '@angular/forms';
import { TitleCasePipe } from '@angular/common';
@Directive({
selector: '[appTitleCase]'
})
export class TitlecaseDirective {
constructor(
public ngControl: NgControl,
public titleCase: TitleCasePipe
) { }
@HostListener('ngModelChange', ['$event'])
onInputChange(value) {
if (value && value !== '' && value.length > 0) {
const arrStr = value.toLowerCase().split(' ');
titleCaseStr = this.titleCase.transform(value);
this.ngControl.valueAccessor.writeValue(titleCaseStr);
}
}
}
import { Directive, HostListener } from '@angular/core';
import { NgControl } from '@angular/forms';
import { TitleCasePipe } from '@angular/common';
@Directive({
selector: '[appTitleCase]'
})
export class TitlecaseDirective {
constructor(
public ngControl: NgControl,
public titleCase: TitleCasePipe
) { }
@HostListener('ngModelChange', ['$event'])
onInputChange(value) {
const arrStr = value.toLowerCase().split(' ');
const titleCaseArr: Array = [];
for (const str of arrStr) {
titleCaseArr.push(str.charAt(0).toUpperCase() + str.slice(1));
}
this.ngControl.valueAccessor.writeValue(titleCaseArr.join(' '));
}
}
import { Directive, HostListener } from '@angular/core';
import { NgControl } from '@angular/forms';
import { TitleCasePipe } from '@angular/common';
@Directive({
selector: '[appTitleCase]'
})
export class TitlecaseDirective {
constructor(
public ngControl: NgControl,
public titleCase: TitleCasePipe
) { }
@HostListener('ngModelChange', ['$event'])
onInputChange(value) {
const arrStr = value.toLowerCase().split(' ');
const titleCaseStr = arrStr.map((str) => (str.charAt(0).toUpperCase() + str.slice(1))).join(' ');
this.ngControl.valueAccessor.writeValue(titleCaseStr);
}
}
import { Directive, HostListener } from '@angular/core';
import { NgControl } from '@angular/forms';
import { TitleCasePipe } from '@angular/common';
@Directive({
selector: '[appTitleCase]'
})
export class TitlecaseDirective {
constructor(
public ngControl: NgControl,
public titleCase: TitleCasePipe
) { }
@HostListener('ngModelChange', ['$event'])
onInputChange(value) {
const arrStr = value.toLowerCase().split(' ');
const titleCaseStr = arrStr.reduce((accumulatedStr, currentStr) => {
const spaceBetweenWords = (accumulatedStr ? ' ' : '');
return accumulatedStr += spaceBetweenWords + (currentStr.charAt(0).toUpperCase() + currentStr.slice(1));
}, '');
this.ngControl.valueAccessor.writeValue(titleCaseStr);
}
}
<input type="text" appTitleCase [(ngModel)]="firstname" name="firstname"/>