0

I'm building a basic html admin panel for my firebase. I created a javascript function to get value from firestore and set in a html table. If My all values in the same collection then I can get this values and put it in a html table with success. But If I have to use two collections in same time then I got problem. To give more details, I'm getting my NonAttendance values from firestore and I want to show student name and surname in the html table. My nonAttendance collection has only user id in STUDENTS array and I want to get students info from Users table using this id. I think I got the problem, it's about promise When I use async function or .then(), Table show nothing, when I don't use any promise and text something in table instead of firestore value, then Table shows them. My javascript function is:

function GetClassNonAttendaceInfoDetail(NonAttendaceInfoID){

//console.log("CLASs===>",NonAttendaceInfoID);
const REF_DATABASE = db.collection("NonAttendance").doc(NonAttendaceInfoID);
REF_DATABASE.get().then((doc) => {

    var showClassNonAttendanceInfo = document.getElementById('showClassNonAttendanceInfo');
    var showClassNonAttendanceInfoDetail = document.getElementById('showClassNonAttendanceInfoDetail');

    showClassNonAttendanceInfo.hidden = true;
    showClassNonAttendanceInfoDetail.style.visibility = 'visible';

    var students = doc.data().STUDENTS;
    //console.log(students);

    var html = '<table class="data-table table nowrap"><thead><tr>';
    html +=
        '                        <th>CLASS</th>\n' +
        '                        <th>STUDENT NO</th>\n' +
        '                        <th>NAME_SURNAME</th>\n' ;
    html += '</tr></thead><tbody>';


    students.forEach(async index => {
        const REF = await db.collection("Users").doc(index).get();
        //console.log(REF.data().NAME);
             
        html += '<tr>';

        html += '<td>' + REF.data().CLASS + '</td>';
        html += '<td>' + REF.data().STUDENT_NO + '</td>';
        html += '<td>' + REF.data().NAME +' '+ REF.data().NAME+ '</td>';

        html += '</tr>';   
        console.log(REF.data());
    
    })
    html += '</tbody></table>';
    showClassNonAttendanceInfoDetail.insertAdjacentHTML("beforeend", html);

}).catch(()=>{
    console.log("Hata")
})
}

This is the google chrome console screenshots

As you see in the picture, in the right side I got my all value from firestore with success, But I can't put it in the table which is left side.

My NonAttendance Collection in Firestore screenshots This is my example of NonAttendance collection of firestore.

1 Answer 1

1

The problem is that forEach does not support async. To solve your problem you sould store the indexes into an array and loop over them with a for loop because those support async. Your code would look like this:

function GetClassNonAttendaceInfoDetail(NonAttendaceInfoID) {
  //console.log("CLASs===>",NonAttendaceInfoID);
  const REF_DATABASE = db.collection("NonAttendance").doc(NonAttendaceInfoID);
  REF_DATABASE.get()
    .then((doc) => {
      var showClassNonAttendanceInfo = document.getElementById(
        "showClassNonAttendanceInfo"
      );
      var showClassNonAttendanceInfoDetail = document.getElementById(
        "showClassNonAttendanceInfoDetail"
      );

      showClassNonAttendanceInfo.hidden = true;
      showClassNonAttendanceInfoDetail.style.visibility = "visible";

      var students = doc.data().STUDENTS;
      //console.log(students);

      var html = '<table class="data-table table nowrap"><thead><tr>';
      html +=
        "                        <th>CLASS</th>\n" +
        "                        <th>STUDENT NO</th>\n" +
        "                        <th>NAME_SURNAME</th>\n";
      html += "</tr></thead><tbody>";

      var indexes = [];

      students.forEach((i) => {
        indexes.push(i);
      });

      for (let i = 0; i < indexes.length; i++) {
        const index = indexes[i];

        const REF = await db.collection("Users").doc(index).get();
        //console.log(REF.data().NAME);

        html += "<tr>";

        html += "<td>" + REF.data().CLASS + "</td>";
        html += "<td>" + REF.data().STUDENT_NO + "</td>";
        html += "<td>" + REF.data().NAME + " " + REF.data().NAME + "</td>";

        html += "</tr>";
        console.log(REF.data());
      }

      html += "</tbody></table>";
      showClassNonAttendanceInfoDetail.insertAdjacentHTML("beforeend", html);
    })
    .catch(() => {
      console.log("Hata");
    });
}

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

4 Comments

You saved my days. Thank you so much. You just forgot to add async. After I added it, it worked perfectly.
One question more I want to ask. I created html table in the function and it works perfectly when I click the button one time. But if I click the button second time to call new values, first table is still on page and second table is coming below the first table. I want first table remove when I click second time.
I solved my another question. Thanks again for helping.
Sorry. Somehow your commend went under my radar. Didn't notice it. Sorry again.

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.