Generating unique IDs
Sometimes you might need to generate a unique id for elements. We’ll talk about the how and the why in this lesson.
What is a unique string
A unique string is a string with many numbers and characters. It has so many characters that it is almost impossible to create the same string twice.
Here’s what a unique strings look like:
const string1 = '577ac755d7fef11100753579'
const string2 = '5b4ef18839cd6500114e04d2'
Since the string is unique, they are often used as an identifier. Hence unique IDs.
Creating a unique string
You can use this code to generate a unique string:
const generateUniqueString = length =>
Math.random().toString(36).substring(2, 2 + length)
This code generates a unique string between 1 to 10 characters. The length
argument determines the numbers of characters generated.
console.log(generateUniqueString(5)) // p9hdi
console.log(generateUniqueString(10)) // lyv38rpujn
We’ll break down this code so you understand what it does.
There are three parts:
Math.random
toString
substring
Math.random
Math.random
is a JavaScript method to produce a random number from 0 to 1. It produces a number with around 16 decimal points. I say around because Math.random
is not consistent.
console.log(Math.random()) // 0.21488604415320722
console.log(Math.random()) // 0.5658986096492693
toString
toString
converts the random number into a string. Every number in JavaScript contains this toString
method. It takes in an argument called a radix
.
Number.toString(radix)
A radix
(or base) is the number of unique digits used in a numeric system. We have many kinds of numeric systems.
For example:
- Booleans have two digits: 0 and 1. They use a
radix
of 2.
- Our normal numeric system has 10 digits: 0-9. This uses a
radix
of 10.
- The hexadecimal numeric system we use for colors has 16 digits: 0-9 and a-f. This uses a
radix
of 16.
If you’ve read about programming, you may have heard about Base 36 and Base 64. Here’s what they mean:
- Base 36 contains 36 digits: the 10 numbers and 26 lower-case letters. 0-9 and a-z.
- Base 64 contains 64 digits: the 10 numbers, both upper and lower-case letters, and the
+
and /
characters.
When you use toString
method that exists on a Number, you can use a radix
between 2 and 36.
Since we’re trying to create a unique string, we want to use the highest number of characters possible. That’s why we use 36 as the radix.
console.log(Math.random().toString(36)) // 0.w4zqan9h1pr
console.log(Math.random().toString(36)) // 0.atfa2xdtzw
Remember Math.random
generates around 16 decimal points? This 16 decimal points becomes 10-11 characters after toString
.
substring
substring
lets you select part of a string. It can take up to two variables:
String.substring(indexStart, indexEnd)
indexStart
tells substring
where to start the selection.
indexEnd
tells substring
where to stop the selection. This character at this index will not be part of the selection. If you did not provide indexEnd
, JavaScript returns all remaining characters.
Example:
console.log('My name is Zell'.substring(1)) // y name is Zell
console.log('My name is Zell'.substring(3, 7)) // name
In generateUniqueString
, we set indexStart
to 2 and an indexEnd
to 2 + length
const generateUniqueString = length =>
Math.random().toString(36).substring(2, 2 + length)
Setting indexStart
to 2 gives us the first character after the decimal point. We don’t want index 0 or 1 because the first two characters are always 0.
.
Setting indexEnd
to 2 + length
lets us change the number of characters for the unique string. A higher number creates a string that is more unique.
Why use unique IDs?
Let’s explain why you need a unique id through an example.
Let’s say you want to create a list of items with JavaScript. Each item needs to have an id
because you need to do something with id
later.
Here’s the HTML most of us will think of.
<ul>
<li id="fruit-0">Apple</li>
<li id="fruit-1">Banana</li>
<li id="fruit-2">Orange</li>
</ul>
To create this HTML, we can use the index
of the item.
const fruits = ['Apple', 'Banana', 'Orange']
const ul = document.querySelector('.ul')
fruits.forEach((fruit, index) => {
const li = document.createElement('li')
li.textContent = fruit
li.id = `fruit-${index}`
ul.appendChild(li)
})
Here’s a question: What happens if you need to create the fourth fruit later?
Most of us will have an urge to continue the indexing. To create the fourth fruit, we need to
- Find the id of the last fruit
- Get the id
- Extract the number from the id
- Increase the number by one
- Set this new number as the id of the new item
(If this sounds tedious, it is. I’m not going to show how to do it. That’s not the point).
Here’s another question: What happens if you need to delete the second fruit? Will you be comfortable having a list with a missing number?
<ul>
<li id="fruit-0">Apple</li>
<li id="fruit-2">Orange</li>
</ul>
This shows a flaw in the numbering system.
A more robust system uses unique strings. We don’t care if elements are added or deleted. They’re going to be unique anyway.
const fruits = ['Apple', 'Banana', 'Orange']
const ul = document.querySelector('.ul')
fruits.forEach((fruit, index) => {
const li = document.createElement('li')
li.textContent = fruit
li.id = generateUniqueString(5)
ul.appendChild('li')
})
<ul>
<li id="v00o0">Apple</li>
<li id="6k9fz">Banana</li>
<li id="j41vt">Orange</li>
</ul>
Note: You won’t need to create your unique ID most of the time. These ids are usually generated on the backend, and you’ll be able to get them when you need them. More details in the Ajax module.
Here’s a fun fact
I didn’t know how to create a unique string before I wrote this lesson.
So I googled.
I found a method on Stack Overflow and I got totally confused. I saw people used Math.random
, toString
and substring
, but I didn’t know what was happening.
So I took everything apart step by step like I showed you in this lesson. And I was able to understand it.
The moral of the story: you don’t need to be perfect when it comes to JavaScript. You can google if you need to. And if you see something you don’t understand, you can take it apart to understand it.