'How to auto populate form fields with json using one select?

I have a form with a select field (for this case is the first name), I want to select one of the options and with that data selected, the other fiels should be auto completed.

The data is comming from an API.

I'm able to have the dropdown working but whenever I select one option the fields aren't being populated.

Can someone help me, please?

This is my javascript:

document.addEventListener('DOMContentLoaded',() => {

    const nomeSelectDrop = document.getElementById('nome');
    const sobrenome = document.getElementById('sobrenome');
    const email = document.getElementById('email');
    const password = document.getElementById('password');

    fetch('http://localhost:5000/user')
        .then(res => {
            return res.json();
        })
        .then(data => {
            let output = "";
            data.forEach(users => {
                output += `<option value = "${users.firstName}">${users.firstName}</option>`;
            })
            nomeSelectDrop.innerHTML = output;
        })
        .catch(err => {
            console.log(err);
        })

    nome.addEventListener('change', (event) => {
        sobrenome.innerHTML = event.target.lastName.value;
        email.innerHTML = event.target.email.value;
        password.innerHTML = event.target.password.value;
    })
})

This is my html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" type="text/css" href="style.css">
    <title>Form Exercise</title>
</head>
<body>
    <form class="formulario">
        <div class="field">
            <label for="nome">Nome:</label>
            <select id="nome" name="nome"></select>
        </div>
        <div class="field">
            <label for="sobrenome">Sobrenome:</label>
            <input type="text" id="sobrenome" name="sobrenome" placeholder="sobrenome" required>
        </div>
        <div class="field">
            <label for="email">E-Mail:</label>
            <input type="email" id="email" name="email" placeholder="e-mail" required>
        </div>        
        <div class="field">
            <label for="password">Password:</label>
            <input type="password" id="password" name="password" placeholder="password" required>
        </div>
        <div class="buttons">
            <input type="submit" name="atualizar" value="Atualizar">
            <input type="submit" name="eliminar" value="Eliminar">
        </div>
    </form>
    
    <script type="text/javascript" src="app.js"></script>
</body>
</html>


Solution 1:[1]

Be aware that some of the #ids and names in HTML has been changed (I think slower reading foreign words -- I'm dumb that way ?). HTMLFormElement and HTMLFormControlsCollection interfaces were used to reference <form>, <input>, and <select>. The most important part is declaring a variable outside of fetch(), then defining that variable as the data within fetch() which brings the data within scope for functions, expressions, etc outside of fetch().

Details are commented in example below

// Reference the <form>
const exc = document.forms.exc;

document.addEventListener('DOMContentLoaded', (e) => {
  /*
  Collect all <select>,<fieldset>,<input> into a HTMLCollection
  */
  let io = exc.elements;
  // Declare a variable outside of fetch()
  let users;

  fetch('https://my.api.mockaroo.com/userlist.json?key=3634fcf0')
    .then(res => {
      return res.json();
    })
    .then(data => {
      /* IMPORTANT
      Define users as JSON data -- now the JSON is in scope within 
      this event handler
      */
      users = data;
      let output = "";
      data.forEach(user => {
        output += `<option value = "${user.first}">${user.first}</option>`;
      });
      /*
      Use insertAdjacentHTML() instead of innerHTML -- it doesn't destroy 
      content it adds to content.
      */
      io.first.insertAdjacentHTML('beforeend', output);
    })
    .catch(err => {});
  /*
  Bind <form> to the change event
  */
  exc.addEventListener('change', (e) => {
    // Reference the tag user is interacting with
    const sel = e.target;

    /*
    If the tag the user is interacting with is a <select>...
    */
    if (sel.matches('select')) {
      // Find the index of selected <option>
      let idx = sel.selectedIndex;

      /*
      users = JSON
      Reference index of users with index of selected <option>
      */
      io.last.value = users[idx].last;
      io.email.value = users[idx].email;
      io.password.value = users[idx].password;
    }
  });
});
html {font: 2ch/1.25 'Segoe UI'}
fieldset {max-width: max-content;}
legend {font-size:1.25rem}
input, select, label {display: inline-block; margin: 2px; font: inherit;}
input:not([type='submit']) {width: 32ch}
[type='submit'] {float: right; cursor: pointer;}
select {width: 33ch}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link href="style.css" rel="stylesheet">
  <title>Form Exercise</title>
</head>

<body>
  <form id="exc">
    <fieldset class="field">
      <legend>User Registration</legend>
      <label for="first">First Name: </label><br>
      <select id="first" name="first">
        <option selected disabled>Select a user</option>
      </select><br>
      <label for="last">Last Name:</label><br>
      <input id="last" name="last" required><br>
      <label for="email">E-Mail:</label><br>
      <input id="email" name="email" type="email" placeholder="[email protected]" required><br>
      <label for="password">Password:</label><br>
      <input id="password" name="password"  type="password" placeholder="Min 8 characters" required>
      <menu class="buttons">
        <input name="update" type="submit" value='Update'>
        <input name="remove" type="submit" value="Remove">
      </menu>
    </fieldset>
  </form>

  <script src="app.js"></script>
</body>

</html>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1