Building a Random Password Generator
Use JavaScript to generate 15 random characters from an array
Hey there! This is Design Nerd speaking 👩🏻💻
I want to share my experience taking an interactive online coding course called Scrimba. It's been incredibly helpful in improving my coding skills. (no ads involved)
I used HTML and CSS to build the interface, and JavaScript to build functions. It was definitely challenging, but let's cut to the chase and get started!
Goal
The task is to build a random password generator that meets the following requirements:
Build it from scratch using HTML, CSS, and JavaScript.
Generate two random passwords when the user clicks the button.
Each password should be 15 characters long and use characters from the given character array.
// Here's the character array
const characters = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9","~","`","!","@","#","$","%","^","&","*","(",")","_","-","+","=","{","[","}","]",",","|",":",";","<",">",".","?",
"/"];
How I solved the problem
Math.random() - get random index number
Initially, I imagined the random password as a slot machine with 15 bars, every bar contains characters array.
Let’s look at the example below.
At this stage, I was attempting to generate a variable named randomNumber, to store the random index.
Here I use Math.random() and Math.floor to achieve that, and console.log it to verify if my code is correct.
let randomNumber = Math.floor(Math.random() * characters.length)
console.log(randomNumber) // 85
It’s working well!
Let’s move on to the next.
for loop - get 15 random characters at once
After obtaining the index, the next step is to generate the index 15 times to obtain 15 random character indexes. This can be achieved using a for loop.
// Create variable for password length
let password.length = 15
for (let i = 0; i < password.length; i++) {
let randomNumber = Math.floor(Math.random() * characters.length)
}
console.log(randomNumber)
// a list of random numbers:
// 46
// 37
// 70
// 24
// 10
// ...
To apply the index back to characters array, I created a variable named password, and assigned password = character[randomNumber]
in for loop
.
// Create variable to store the password
let password = ""
let passwordLength = 15
for (let i = 0; i < password.length; i++) {
let randomNumber = Math.floor(Math.random() * characters.length)
password = characters[randomNumber]
}
console.log(password) // <
But when I console.log(password), it only has one character.
I need to concatenate all the passwords in each loop.
So I re-assigned the password to password += characters[randomNumber]
I console.log(password), it showed J6m)NWw.yXF)>~S
. It’s 15 random characters from characters array, exactly what I wanted!
let password = ""
let passwordLength = 15
for (let i = 0; i < password.length; i++) {
let randomNumber = Math.floor(Math.random() * characters.length)
password += characters[randomNumber]
}
console.log(password) // J6m)NWw.yXF)>~S
Return
However, as I learned in JavaScript, console.log
is used for examining code and not for storing data. Therefore, I needed to use return
to render the value from for loop
.
let password = ""
let passwordLength = 15
for (let i = 0; i < password.length; i++) {
let randomNumber = Math.floor(Math.random() * characters.length)
password += characters[randomNumber]
}
console.log(password) // J6m)NWw.yXF)>~S
// render the value from for loop, need to use return
When I tried to verify my code with console.log
, it resulted in a syntax error: "Illegal return statement.”
let password = ""
let passwordLength = 15
for (let i = 0; i < password.length; i++) {
let randomNumber = Math.floor(Math.random() * characters.length)
password += characters[randomNumber]
return password
}
console.log(password) // !SyntaxError: Illegal return statement
And here’s what Google said:
💡 The "Uncaught SyntaxError: Illegal return statement" error occurs, whenever JavaScript comes across a return statement outside of a function. return
can only be used inside of functions.
To fix this, I created a function outside of the code that generates a list of 15 random characters using the return
statement.
However, the function only generated one character.
I'm not sure how I ended up back at this stage again. 😅
let password = ""
let passwordLength = 15
function randomPassword(){
for (let i = 0; i < passwordLength; i++) {
let randomNumber = Math.floor(Math.random() * characters.length)
password += characters[randomNumber]
return password
}
}
console.log(randomPassword()) // s
After experimenting a thousand times more, I found out why - I put the return
in the wrong position.
💡 Your loop actually returns when it first reaches the return
and never runs after. This is how return works, returning back to where it was called. You would be better to place your return to run AFTER the loop has completed.
Hmmm... so the return
statement should be placed inside the function but outside of the for
loop. As explained in this Stack Overflow post, placing the return
statement inside the for
loop caused it to stop after generating the first value.
After repositioning the return
statement, the function is working as intended and generating 15 random characters again! 🥺
let password = ""
let passwordLength = 15
function randomPassword(){
for (let i = 0; i < passwordLength; i++) {
let randomNumber = Math.floor(Math.random() * characters.length)
password += characters[randomNumber]
}
return password
}
console.log(randomPassword()) // Q.i?GEnb_{mWfaP
Show two sets of passwords when the button is clicked
TypeError: getElementById is null
In my JavaScript code, I created two variables using getElementById
. However, when I tried to console.log
them, they returned "null."
// Create 2 variables for passwords
let passwordEl = document.getElementById("password-el")
console.log(passwordEl) // null
I was confused as to why my variable was null even though the CSS and HTML were functioning properly. After some research, I discovered that the issue occurred because I had placed the HTML <script>
tag in the wrong order. It should be placed after the last element and before the closing </body>
tag.
<html>
<head>
<link rel="stylesheet" href="index.css">
</head>
<body>
<div class="hero">
<h1 id>Generate a</h1>
<h1 id="H1-green">random password</h1>
<p id="note">Never use a insecure password again.</p>
</div>
<button>Generate passwords</button>
<script src="index.js"></script>
<hr>
<div class="passwords">
<p class="password" id="password-el">12354</p>
<p class="password" id="password-el2"></p>
</div>
</body>
</html>
After placing the script in the correct order, right before </body>, the result is just what I wanted!
<html>
<head>
<link rel="stylesheet" href="index.css">
</head>
<body>
<div class="hero">
<h1 id>Generate a</h1>
<h1 id="H1-green">random password</h1>
<p id="note">Never use a insecure password again.</p>
</div>
<button id="btn" onclick="renderPassword()">Generate passwords</button>
<hr>
<div class="passwords">
<p class="password" id="password-el"></p>
<p class="password" id="password-el2"></p>
</div>
<script src="index.js"></script>
</body>
</html>
Displaying numbers in paragraphs by .textContent
Now, we just need to create a function that shows two sets of random passwords when the "Generate Passwords" button is clicked.
let passwordEl = document.getElementById("password-el")
let passwordEl2 = document.getElementById("password-el2")
let passwordLength = 15
let password = ""
function randomPassword() {
for (let i = 0; i < passwordLength; i++) {
let randomNumber = Math.floor(Math.random() * characters.length)
password += characters[randomNumber]
}
return password
}
// When the button "Generate Passwords" is clicked,
// two sets of random passwords will appear.
function generatePassword(){
randomPassword()
passwordEl.textContent = randomPassword()
passwordEl2.textContent = randomPassword()
}
Emptying the Previous Value
Just when I thought things were working well and about to come to an end, a new problem would always emerge: when the button is clicked a second time, the previous value is still there. If I keep clicking it, the numbers will pile up like a family tree of rats. 🙂
So, how can I make the password value empty every time the button is clicked?
I added password = ""
in the randomPassword()
function so that when the function is called, the first thing it does is make the password an empty string.
let passwordEl = document.getElementById("password-el")
let passwordEl2 = document.getElementById("password-el2")
let passwordLength = 15
let password = ""
function randomPassword() {
for (let i = 0; i < passwordLength; i++) {
let randomNumber = Math.floor(Math.random() * characters.length)
password += characters[randomNumber]
// password += characters[randomNumber]
}
return password
}
// when the button Generate passwords is clicked,
// two sets of random passwords would show.
function generatePassword(){
randomPassword()
passwordEl.textContent = randomPassword()
passwordEl2.textContent = randomPassword()
}
Finally, I can say: IT'S DONE!
When I run the code, it’s working smoothly! 🥳
That's all the JavaScript code I wrote for this project. If you want to see the HTML and CSS code, it's on my GitHub.
I hope you find my article helpful and enjoy reading it. I was stuck on this chapter for almost two weeks and felt guilty for not learning new things from Scrimba. However, blogging about my coding process helps me muscle-memorize the syntax and dive deeper into the concepts, so I enjoy it very much.
If you have any questions or notice any mistakes, feel free to leave a comment.
Keep coding, and good luck on your journey! 🍀