Home > Net >  Cannot pass array object from map function as argument javascript
Cannot pass array object from map function as argument javascript

Time:06-23

I am trying to figure out why I cannot pass array object from map function as argument to function createModal(student) that is called onclick:
The error is caused by the parameter because when I tried function createModal() it worked fine.

const allWorkshops = await fetch("/api/workshops/detail");
const data = await allWorkshops.json();
result.innerHTML = "";
counter = 0;

data.forEach((workshop) => {
  ...
  ${workshop.students.map(student =>
     `<li >
        <a data-bs-toggle="modal" data-bs-target="#studentModal" type="button" onclick="createModal(${student})">${student.first_name} ${student.last_name}</a>
      </li>`
  ).join("")}
  ...
});

I have seen this (and this) question and tried changing the code as following but it did not work either:

...
${workshop.students.map(function(student) {
   var studentCopy = JSON.parse(JSON.stringify(student));
   return `<li >
             <a data-bs-toggle="modal" data-bs-target="#studentModal" type="button" onclick="createModal(${studentCopy})">${student.first_name} ${student.last_name}</a>
           </li>`
}).join("")}
...

Unfortunately I don't know the exact error because the only thing I see in inspect in Chrome is this. Which is at the beggining of index file and does not help me.

Uncaught SyntaxError: Unexpected identifier (at (index):1:21)

EDIT: I have updated the code to look as following. It kinda works but the problem is that is have a table for workshops and every row has a list with the students inside and instead of appending students to the right workshop it appends them to the first list other are empty.

const workshopList = document.querySelector(".workshop-list");

async function getData(){
  const allWorkshops = await fetch("/api/workshops/detail");
  const data = await allWorkshops.json();
  data.forEach((workshop) => {
      var studentList = document.querySelector(".student-list");
      const tr = document.createElement("tr");
      tr.classList.add("responsive-table__row");
      tr.innerHTML = `
          <td >
              <ul >
                  ${workshop.students.forEach(student => {
                      let li = document.createElement('li');
                      li.classList.add('list-group-item');
                      let anchor = document.createElement('a');
                      anchor.dataset.bsToggle = 'modal';
                      anchor.dataset.bsTarget = '#studentModal';
                      anchor.setAttribute('type', 'button');
                      anchor.addEventListener('click', () => createModal(student));
                      anchor.innerText = student.last_name;
                      li.appendChild(anchor);
                      studentList.appendChild(li);
                  })}
              </ul>
          </td>
      `
      workshopList.appendChild(tr);
  });
};

CodePudding user response:

student is an object. When you try to interpolate it into the template literal, it gets turned into the string [Object object], which isn't a meaningful argument to create_modal().

Instead of interpolating, you should create the element using DOM methods, and use addEventListener() with a closure to bind the click listener.

data.forEach((workshop) => {
  //...
  workshop.students.forEach(student => {
    let li = document.createElement('li');
    li.classList.add('list-group-item');
    let anchor = document.createElement('a');
    anchor.dataset.bsToggle = 'modal';
    anchor.dataset.bsTarget = '#studentModal';
    anchor.setAttribute('type', 'button');
    anchor.addEventListener('click', () => createModal(student));
    anchor.innerText = student.last_name;
    li.appendChild(anchor);
    studentList.appendChild(li);
  });
  //...
});

  • Related