JavaScript:How do i put dynamic content into a modal?

When i click on a button i am able to open up a modal, however i want to be able to fill Select form in that modal with data that i am getting from JSON server.I keep getting this error:
TypeError: “this.techSelectOptions is null”
Also i am using Materialize as a css framework.
Any help would be appreciated.
This is a link to my GitHub repo:


HTML

 <!--Floating button-->
    <div class="fixed-action-btn">
      <a
        href="#add-log-modal"
        class="btn-floating btn-large blue darken-2 modal-trigger new-log"
      >
        <i class="large material-icons">add</i>
      </a>
<!--Log modal-->
<div id="add-log-modal" class="modal" style="width:75%; height:75%;">
        <div class="modal-content">
 <div class="row">
            <div class="input-field">
              <select name="tech" value="tech" class="browser-default">
                <option value="" disabled>
                  Select Technician
                </option>
                <span id="tech-select-options"></span>
              </select>
            </div>
          </div>
</div>

app.js

const addLog = () => {
  axios
    .get("http://localhost:5000/techs")
    .then(response => ui.showTechs(response.data))
    .catch(err => console.log(err));
};
document.querySelector(".new-log").addEventListener("click", addLog);

ui.js

class UI {
  constructor() {
    this.techSelectOptions = document.querySelector("#tech-select-options");
  }
showTechs(techs) {
   
    let output = "";

    techs.forEach(tech => {
      output += `
      <option value="${tech.firstName} ${tech.lastName}"style="display:block">
      ${tech.firstName} ${tech.lastName}</option>
      `;
    });
    this.techSelectOptions.innerHTML = output;
  }
}

export const ui = new UI();

db.json

{
"techs": [
    {
      "id": 1,
      "firstName": "John",
      "lastName": "Doe"
    },
    {
      "id": 2,
      "firstName": "Sam",
      "lastName": "Smith"
    },
    {
      "id": 3,
      "firstName": "Sara",
      "lastName": "Wilson"
    },
    {
      "firstName": "Jennifer",
      "lastName": "Williams",
      "id": 4
    }
  ]
}

I think you need some changes in your code:

  1. you need to remove <span id="tech-select-options"></span> and set <option> directly to the <select> element i.e.
this.techSelectOptions = document.querySelector("select");
  1. Since data returned by axios is an object and you can not use forEach() function on an object so you need to get array for forEach i.e.
showTechs(data) {
    let output = "";

    data.techs.forEach(tech => {
      output += `<option value="${tech.firstName} ${tech.lastName}"style="display:block">
      ${tech.firstName} ${tech.lastName}</option> `;
    })
  1. to show option in select use following code :
this.techSelectOptions.innerHTML+=output;

hope this will help but if it didn’t help then use console.log() to print data returned by db.json file and check it is returning data or not .

1 Like

Yes, the issue was that i didn t set <option> directly to the <select> element.It works now.Thank you so much for your help.

Sorry to bother you again but i am experiencing similar problem in the same app.I am unable to display data in the UI that i am getting from the server.I don t know how many times i checked everything but i am unable to find an error and i don t see anything in the console.
HTML

<ul>
        <li>
          <a
            href="#tech-list-modal"
            class="btn-floating green modal-trigger tech-collection"
            ><i class="material-icons">person</i></a
          >
          <!--Techlist modal-->
          <div id="tech-list-modal" class="modal">
            <div class="modal-content">
              <h4>Technician List</h4>
              <ul class="collection" id="tech-workers"></ul>
            </div>
          </div>
        </li>
</ul>

app.js

//Show list of technicians

const showTechList = () => {
  axios
    .get("http://localhost:5000/techs")
    .then(response => ui.showList(response.data))
    .catch(err => console.log(err));
};

document
  .querySelector(".tech-collection")
  .addEventListener("click", showTechList);

ui.js

class UI {
  constructor() {
    this.techList = document.querySelector("#tech-workers");
  }
showList(techs) {
    let output = "";

    techs.forEach(tech => {
      output += `
      <li class="collection-item">
      <div>
       ${tech.firstName} ${tech.lastName}
        <a href="#!" class="secondary-content delete-tech" data-id="${tech.id}">
          <i class="material-icons grey-text">delete</i>
        </a>
      </div>
    </li>
      `;
    });
    this.techList.innerHTML = output;
  }
}

export const ui = new UI();

db.json

{
"techs": [
    {
      "id": 1,
      "firstName": "John",
      "lastName": "Doe"
    },
    {
      "id": 2,
      "firstName": "Sam",
      "lastName": "Smith"
    },
    {
      "id": 3,
      "firstName": "Sara",
      "lastName": "Wilson"
    },
    {
      "firstName": "Jennifer",
      "lastName": "Williams",
      "id": 4
    }
  ]
}

when I tried your code it give me error TypeError: techs.forEach is not a function, but as I said above we can’t use forEach() on objects ,so i passed response.data.techs as ui.showList function argument i.e. ui.showList(response.data.techs) and now it is working for me you can see the image .