0

I am trying to convert an array to string using array.join() or array.toString() but it's not working as it's supposed to work. When I console.log it stays as an array.

I've the intuition that this issue comes from something related to function scopes, but I could not figure it out yet.

The project I'm trying to build is a password generator.

const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
const numbers = "0123456789";
const symbols = "!@#$%^&*_-+=";

const button = document.querySelector(".gen-pass");

button.addEventListener("click", (e) => {

  let password = [];
  
  for (let i = 0; i < 4; i++) {
    let randomLetters = letters[Math.floor(Math.random() * letters.length)];
    let randomNumbers = numbers[Math.floor(Math.random() * numbers.length)];
    let randomSymbols = symbols[Math.floor(Math.random() * symbols.length)];

    password.push(randomLetters, randomNumbers, randomSymbols);
    password.join();
  }

  console.log(password);
});
<button class="gen-pass">Generate!</button>

3
  • 4
    .join() returns a new string. Doesn't change the variable to be a string instead. It cannot, as that's not how JS can ever work. Commented May 9, 2022 at 14:17
  • 6
    You should do password.join only once after your array is complete, not inside the loop Commented May 9, 2022 at 14:18
  • 3
    The Array's method join returns a string. Try strPassword = password.join();. Here is the documentation Commented May 9, 2022 at 14:19

5 Answers 5

1

Array.prototype.join() returns a string. It does not change the object it is called on.

You may want to create a new variable or mutate password after the for loop has completed like so:

const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
const numbers = "0123456789";
const symbols = "!@#$%^&*_-+=";
let password = [];
for (let i = 0; i < 4; i++) {
    let randomLetters = letters[Math.floor(Math.random() * letters.length)];
    let randomNumbers = numbers[Math.floor(Math.random() * numbers.length)];
    let randomSymbols = symbols[Math.floor(Math.random() * symbols.length)];

    password.push(randomLetters, randomNumbers, randomSymbols);
    
  }
  
  password = password.join('');

  console.log(password);

Sign up to request clarification or add additional context in comments.

Comments

1

You can do something like this

const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
const numbers = "0123456789";
const symbols = "!@#$%^&*_-+=";


const button = document.querySelector(".gen-pass");

button.addEventListener("click", (e) => {

  e.preventDefault();

  const password = Array(4).fill(0).flatMap(_ => 
    [
      letters[Math.floor(Math.random() * letters.length)],
      numbers[Math.floor(Math.random() * numbers.length)],
      symbols[Math.floor(Math.random() * symbols.length)]
    ]
  ).join('');
  

  console.log(password);
});
<button class="gen-pass">GENERATE</button>

basically this code generate and array of [letter, number, symbol, ...] and then it join them together

1 Comment

While this is a larger change to the OP's code, I like this answer best. It is the most concise. Though not as easy for beginner coders to understand.
1

const button = document.querySelector(".gen-pass");

button.addEventListener("click", (e) => {

  e.preventDefault();

  let password = [];
  let formattedPassword = '';

  for (let i = 0; i < 4; i++) {
    let randomLetters = letters[Math.floor(Math.random() * letters.length)];
    let randomNumbers = numbers[Math.floor(Math.random() * numbers.length)];
    let randomSymbols = symbols[Math.floor(Math.random() * symbols.length)];

    password.push(randomLetters, randomNumbers, randomSymbols);

  }

  formattedPassword = password.join('');
  console.log(password, formattedPassword);
});

2 Comments

You shouldn't put the .join within the for loop. Also your formatting is a bit off.
thanks Jeff for pointing it out :)
0

Try changing your return to the following. This moves the join to occur once at the end of password creation and removes the ,s by telling .join to replace all ,s with empty strings:

const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
const numbers = "0123456789";
const symbols = "!@#$%^&*_-+=";
const button = document.querySelector(".gen-pass");

button.addEventListener("click", (e) => {

  e.preventDefault();

  let password = [];
  
  for (let i = 0; i < 4; i++) {
    let randomLetters = letters[Math.floor(Math.random() * letters.length)];
    let randomNumbers = numbers[Math.floor(Math.random() * numbers.length)];
    let randomSymbols = symbols[Math.floor(Math.random() * symbols.length)];

    password.push(randomLetters, randomNumbers, randomSymbols);
  }

  console.log(password.join(""));
});
<button type="button" class="gen-pass">Generate Password</button>

Comments

0

The easiest way I can think of is by using JSON which is known for converting data to strings. Check this stringify function out here: https://www.w3schools.com/js/js_json_stringify.asp?msclkid=e8639fd0cfa411eca470fe06b0ce6da7

1 Comment

You are new to SO, so I wanted to give you a bit of advice. When answering questions it is best to put examples or explanation as to the solution rather than an external link. Among many reasons, a major one is that we can not guarantee that link will be good a year from now. It is fine to link to something external WITH an answer so a user may look for further reading.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.