Search code examples
javascriptarraysundefined

I'm having some array[i] is undefined error and I can't find a way of working around it


I'm working in a dispatch center, we are using "Astrid Netviewer" on planning our teams. Netviewer runs in Firefox browers. The way we are told to use Netviewer is very time consuming, and very cumbersome.

As Netviewer is browser based, I thought: "Why shouldn't I automate it?" using JavaScript.

Here is a simple explanation of the procedure. At the first page we have a couple of rows/columns. "Ploeg ID" means team, every team has a couple of employees in it, you can find the employee in the column "Personeel" every employee has his own 44xxxxx number.

foto1

Every shift, at the end of the day, we need to clear all the information in every single "Ploeg ID".

How do we do this, in the column "Ploeg ID" we click on the corresponding "Ploeg ID", for example GENT2203. We get redirected to a webpage for example /netviewer/UnitID=GENT2203. On that page we need top click the "wis alle personeel/toestellen"

foto2

We have to do this for more then 40 teams, 3 times a day...

What I want to do, is write a script, that locates all of the "PLOEG ID"'s in the html table, put them in a array, removes all the unnecessary information in the array, loops through the array, opens' "/netviewer/UnitID="+array[1] ' and performs two get.Element clicks.

Using the following code is managed to filter out "Ploeg ID", the "employee number" and put them all in a array. I use the following code to do this:

var tableObj = document.getElementById( "UnitItems" );
var arr = [];
var allTRs = tableObj.getElementsByTagName( "tr" );


for ( var trCounter = 0; trCounter < allTRs.length; trCounter++ )
{
    var tmpArr = [];
    var allTDsInTR = allTRs[ trCounter ].getElementsByTagName( "a" );
    for ( var tdCounter = 0; tdCounter < allTDsInTR.length; tdCounter++ )
    {
        tmpArr.push( allTDsInTR[ tdCounter ].innerHTML );
    }
    arr.push( tmpArr );
}
console.log( arr );

The html code (sorry for the picture):

foto3

The result I get with the code above:

foto4

As you see I get a nested Array, and only need the first value of that nested Array so arr[2][0].

But at this point I got stuck... and I'm getting errors.

This is the code I have so far. As I only need the GENTXXXX is push the first value in in arr[] in a new arrClear[].

var tableObj = document.getElementById( "UnitItems" );
var arr = [];
var allTRs = tableObj.getElementsByTagName( "tr" );
var arrClean = [];


for ( var trCounter = 0; trCounter < allTRs.length; trCounter++ )
{
    var tmpArr = [];
    var allTDsInTR = allTRs[ trCounter ].getElementsByTagName( "a" );
    for ( var tdCounter = 0; tdCounter < allTDsInTR.length; tdCounter++ )
    {
        tmpArr.push( allTDsInTR[ tdCounter ].innerHTML );
    }
    arr.push( tmpArr );
}
//console.log( arr );

for (var j = 1; j < arr.length; j++){

        arrClean.push(arr[j][0]);
        arrClean[j] = arrClean[j].toString();   
        //window.open("/NetViewer/LineupsCommand/AddUnitInformation?unitID="+arrClean[j]+"&lineupName=Z_GENT_1_INT_MAANDAG_2&agencyID=Z_GENT", "_self");
        //document.getElementById("btnResetAllEmployees").click();
        //document.getElementById("btnAddUnitInformation").click();
}

but I get the following error "Uncaught TypeError: arrClean[j] is undefined". I added arrClean[j] = arrClean[j].toString(); behing arrClean.push(arr[j][0]); because of the typeError? But that does not fix it.

If I uncommand window.open arrclean[j], I get /NetViewer/LineupsCommand/AddUnitInformation?unitID=undefined&lineupName=Z_GENT_1_INT_MAANDAG_2&agencyID=Z_GENT

How can I solve the undefined error? Or maybe a shorter way to tackle my problem?

I also tried, let instead of var, but that doesn't seems to work. A second possible solution I found on stack is using foreach instead of a regular for loop, but I can't wrap my head around it...


Solution

  • I put a rough HTML together using your image.

    For my answer, I use querySelectorAll to get all of the table's TDs.

    Then I loop through them and look if the textContent contains GENT (this can be easily changed). If it does, then push the textContent which will ignore the anchors and other HTML.

    const tds = document.querySelectorAll("#UnitItems td");
    let ids = [];
    tds.forEach((td) => {
      if (td.textContent.includes("GENT")) {
        ids.push(td.textContent)
      }
    });
    
    ids.forEach((id) => {
      console.log("/NetViewer/LineupsCommand/AddUnitInformation?unitID=" + id + "&lineupName=Z_GENT_1_INT_MAANDAG_2&agencyID=Z_GENT", "_self");
    });
    <table id="UnitItems">
      <tr>
        <td></td>
        <td><a href="">GENT202</a></td>
        <td></td>
        <td></td>
      </tr>
      <tr>
        <td></td>
        <td><a href="">GENT2023</a></td>
        <td></td>
        <td></td>
      </tr>
    
      <tr>
        <td></td>
        <td><a href="">GENT2025</a></td>
        <td></td>
        <td></td>
      </tr>
    </table>