I'm making a course and one of the tasks is to generate four different passwords that should fill the four different paragraphs <p id="first"></p>, <p id="second"></p>, <p id="third"></p>, <p id="fourth"></p>
I have created a script that creates a password but somehow it doesn't print the first password. When I do console.log(password) it shows that creates a password on the console. But when I try to put first.textContent = password it shows nothing.
let chars = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "A", "B", "C", "D"]
let number = 10
let password = ""
let first = document.getElementById("first")
let second = document.getElementById("second")
let third = document.getElementById("third")
let fourth = document.getElementById("fourth")
function generate() {
for (let i = 0; i < number; i++) {
let passwordChar = Math.floor(Math.random() * chars.length)
password += chars[passwordChar]
return password
}
}
first.textContent = password
<html>
<head>
<link rel="stylesheet" href="index.css">
</head>
<body>
<h1>Generate a random password</h1>
<p id="description">Never use an insecure password again</p>
<button onclick="generate()">Generate passwords</button>
<p id="line"></p>
<p id="first"></p>
<p id="second"></p>
<p id="third"></p>
<p id="fourth"></p>
</body>
</html>
I'm also stuck to generate each time the function is running a new password and put it on the next paragraph. Like so:
first.textContent = password
second.textContent = password
third.textContent = password
fourth.textContent = password
Any help will be appreciated
Please pay attention to every single line of code you write. Every single line has a meaning!
return part should be after the for loop:function generate() {
let pw = ''
for (let i = 0; i < number; i++) {
let passwordChar = Math.floor(Math.random() * chars.length)
pw += chars[passwordChar]
}
return pw
}
generate():first.textContent = generate()
second.textContent = generate()
third.textContent = generate()
fourth.textContent = generate()
It is generally not a good idea to use inline event handlers.
Here is a snippet using event delegation. For retrieving and filling certain elements, use a single identifier for them (here: a data attribute). Now you can loop the elements and fill them with your password values (forEach). In this snippet the passwords are generated using Array.map.
document.addEventListener(`click`, handle);
function handle(evt) {
// ↓ only do things if button#passGen is clicked
if (evt.target.id === `passGen`) {
return generate();
}
}
function generate() {
const chars = `0123456789abcdefghijk`;
document.querySelectorAll(`[data-passgenerated]`)
// ↑ retrieve all p[data-passgenerated]
// ↓ Loop through the elements and fill them
.forEach(elem => elem.textContent = [...Array(10)].map(v =>
chars[Math.floor(Math.random() * chars.length)]).join(``)
);
}
<p data-passgenerated="1"></p>
<p data-passgenerated="2"></p>
<p data-passgenerated="3"></p>
<p data-passgenerated="4"></p>
<button id="passGen">Create passwords</button>
The main thing going wrong is that first.textContent = password is placed outside of generate(), so it will be set to the initial password value (empty string), but is never updated.
Without changing too much, I suggest splitting the code into two functions. One to generate a password, and one that assigns element contents to these randomly generated passwords.
function generatePassword() {
const chars = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "A", "B", "C", "D"];
let password = "";
for (let i = 0; i < 10; i++) {
const passwordChar = Math.floor(Math.random() * chars.length);
password += chars[passwordChar];
}
// I've moved the return down, because you return after generating only 1 character
return password;
}
function loadPasswords() {
document.getElementById("first").textContent = generatePassword();
document.getElementById("second").textContent = generatePassword();
document.getElementById("third").textContent = generatePassword();
document.getElementById("fourth").textContent = generatePassword();
}
<h1>Generate a random password</h1>
<p id="description">Never use an insecure password again</p>
<button onclick="loadPasswords()">Generate passwords</button>
<p id="line"></p>
<p id="first"></p>
<p id="second"></p>
<p id="third"></p>
<p id="fourth"></p>
Like already stated by other answers, I would personally avoid using inline handlers and use addEventListener() instead.