loading...
Cover image for String Pad in JavaScript

String Pad in JavaScript

samanthaming profile image Samantha Ming Originally published at samanthaming.com ・5 min read

Alt Text

It's super easy to pad a string! Just pass in your desired string and length. The string will be padded until the length has been met. Use padStart to apply it at the start and padEnd to apply it at the end πŸŽ€

const string = 'hi';

string.padStart(3, 'c'); // "chi"

string.padEnd(4, 'l'); // "hill"

Syntax

This is the syntax of how to use the method.

string.padStart(<maxLength>, <padString>)

string.padEnd(<maxLength>, <padString>)

Understanding the Parameters

padEnd and padStart accepts the same parameters.

1. maxLength

This is the max length of the result string.

const result = string.padStart(5);

result.length; // 5

When I was learning this, this took me awhile to grasp. I kept thinking it was the amount of times the pad string argument would be repeated. So just want to stress that this parameter is setting the MAX or targeted length of the result string. It is NOT the amount the pad string is repeated. But you're way smarter than I am, so I'm sure you did not have this confusion πŸ˜†

2. padString

This is the string you want to pad your string with. This is optional. If you don't specify anything, the default would be an empty space.

'hi'.padStart(5);

// Same as
'hi'.padStart(5, ' ');

And if you try to pass an an empty string, then no padding will happen.

const result = 'hi'.padStart(5, 'hi');

result; // ''
result.length; // 2

How it handles other data types

For the second parameter, padString, it accepts a string. If you try to pass any other data types. It will be coerced into a string using toString and that will be used. So let's see what happens when we use the toString on different value types.

// NUMBER
(100).toString(); // '100'

// BOOLEAN
true.toString();   // 'true'
false.toString();  // 'false'

// ARRAY
['A'].toString(); // 'A'
[''].toString();  // ''

// OBJECT
({}).toString();         // '[object Object]'
({hi: 'hi'}).toString(); // '[object Object]'

Now knowing this, let's see if pass these other value types to padStart (padEnd will have the same behaviour).

'SAM'.padStart(8, 100);    // '10010SAM'

'SAM'.padStart(8, true);   // 'truetSAM'
'SAM'.padStart(8, false);  // 'falseSAM'

'SAM'.padStart(5, ['']);   // 'SAM'
'SAM'.padStart(5, ['hi']); // 'hiSAM'

'SAM'.padStart(18, {});         // '[object Object]SAM'
'SAM'.padStart(18, {hi: 'hi'}); // '[object Object]SAM'

Handling undefined

But here's an interesting one. When you try to coerce undefined, you will get a TypeError

undefined.toString(); // TypeError: Cannot read property 'toString' of undefined

But when you pass in undefined as your second argument, you get this:

'SAM'.padStart(10, undefined);
// '       SAM'

So when I said the padString argument will be coerced using toString, did I just lie to you πŸ™Š Well, let's dive into the spec:

ECMAScript Spec If fillString is undefined, let filler be the String value consisting solely of the code unit 0x0020 (SPACE).

Okay, so let me update what I said! Unless, it's undefined, everything other data type you passed will be coerced using toString πŸ˜‰

What if padString exceed maxLength?

When the first argument maxLength doesn't allow enough length for your first argument, padString, it will simply be ignored.

'hi'.padEnd(2, 'SAM');
// 'hi'

Or if it would be cut off. Remember maxLength means the maximum length your padString is allowed to occupy minus what's being occupied by the string.

'hi'.padEnd(7, 'SAMANTHA');
// 'hiSAMAN'

And if your first argument, maxLength is less then your string, it will simply just return the string.

'hello'.padEnd(1, 'SAM');
// 'hello'

padStart/padEnd vs padLeft/padRight

In a previous code note, I covered String Trim where I mentioned the trim methods had aliases.

  • trimLeft is an alias for trimStart
  • trimRight is an alias for trimEnd

But for string pad methods, there are no aliases. So do NOT use padLeft and padRight, they do not exist. It is also the reason why you are encouraged to not use the trim aliases so there is better consistency in your code base πŸ˜„

Use Case

Tabular Formatting with padEnd

A good use case of the string pad methods is for formatting. I covered how to display string in tabular format.

Right Aligning String with padStart

You can format right alignment with padStart.

console.log('JavaScript'.padStart(15));
console.log('HTML'.padStart(15));
console.log('CSS'.padStart(15));
console.log('Vue'.padStart(15));

This will output:

     JavaScript
           HTML
            CSS
            Vue

Receipt formatting

With the knowledge of right alignment formatting, you can mimic a receipt print out like this:

const purchase = [
  ['Masks', '9.99'],
  ['Shirt', '20.00'],
  ['Jacket', '200.00'],
  ['Gloves', '10.00'],
];

purchase.forEach(([item, price]) => {
  console.log(item + price.padStart(20 - item.length));
});

This will output:

Masks           9.99
Shirt          20.00
Jacket        200.00
Gloves         10.00

Masking Numbers

We can also use it to display masked numbers.

const bankNumber = '2222 2222 2222 2222';
const last4Digits = bankNumber.slice(-4);

last4Digits.padStart(bankNumber.length, '*');
// ***************2222

Thanks @cilly_boloe

Browser Support

padStart and padEnd were introduced at the same time, so they share similar browser support. All but Internet Explorer, but are we really surprised πŸ˜…

Browser
Chrome βœ…
Firefox βœ…
Safari βœ…
Edge βœ…
Internet Explorer ❌

Polyfill

For IE or older browser support, please see this polyfill

Community Input

@ljc_dev: I saw someone use it to add an extra zero in their clock when the number is one digit.

Resources


Thanks for reading ❀
To find more code tidbits, please visit samanthaming.com

🎨 Instagram 🌟 Twitter πŸ‘©πŸ»β€πŸ’» SamanthaMing.com

Discussion

pic
Editor guide
Collapse
functional_js profile image
Functional Javascript

Excellent work Samantha.

A couple of these might come in handy so I utility-ized them...

Utility 1

/**
@func
pretty format two columns as a text-based table

@param {string[][]} a
@return {string} multiline formatted str
*/
const formatTwoCol = a => a.map(([col1, col2]) => col1 + col2.padStart(20 - col1.length)).join("\n");

//@tests
const purchaseItems = [
  ["Masks", "9.99"],
  ["Shirt", "20.00"],
  ["Jacket", "200.00"],
  ["Gloves", "10.00"],
];

console.log(formatTwoCol(purchaseItems));
/*
output:
Masks           9.99
Shirt          20.00
Jacket        200.00
Gloves         10.00

*/

Utility 2

/**
@func
mask a credit card number with asterisks

@tags
security

@algor
get last 4 numbers
- then left-pad these 4 numbers with asterisks
- by the count of the remaining numbers

@param {string} cc - Credit Card number as a string, space separated per 4 digits
@return {string} - masked str
*/
const maskCreditCardNumber = cc => cc.slice(-4).padStart(cc.length, "*");

//@tests
console.log(maskCreditCardNumber("2222 2222 2222 2222"));
/*
output:
***************2222

*/
Collapse
samanthaming profile image
Samantha Ming Author

WHoa! these are fantastic πŸ‘ Thanks for sharing πŸ™Œ

Collapse
scroung720 profile image
scroung720

This is an amazing article. Great writing. Keep it up!

Collapse
samanthaming profile image
Samantha Ming Author

You bet!! thanks for the encouraging words πŸ’ͺ