ScrollTop function generates Undefined JS error

I have some simple code which looks for a date value in a table and scrolls to that position. The below code works but also generates an undefined error which breaks other features.

$(window).scrollTop($("*:contains('<%=ScrollDate%>')").parent('tr').offset().top -40);

ScrollDate is system generated and changes every day based on system dates.

The error is

Uncaught TypeError: $(…).parent(…).offset() is undefined

I am using https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js for this.

<table class="ramadan-time table-wrapper-scroll-x my-custom-scrollbar">
  <thead>
    <tr>
      <th scope="col">Date</th>
      <th scope="col">Day</th>
      <th scope="col">Ramadan</th>
      <th scope="col">April/May</th>
      <th scope="col">Imsak</th>
      <th scope="col">Fajr</th>
      <th scope="col">Sunrise</th>
      <th scope="col">Dhuhr</th>
      <th scope="col">Asr</th>
      <th scope="col">Maghrib</th>
      <th scope="col">Isha</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td class="Date" data-label="Date">13-04-2021</td>
      <td data-label="Day">Tuesday</td>
      <td data-label="Ramadan">1</td>
      <td data-label="April/May">13</td>
      <td data-label="Imsak">4:29</td>
      <td data-label="Fajr">4:39</td>
      <td data-label="Sunrise">5:55</td>
      <td data-label="Dhuhr">12:22</td>
      <td data-label="Asr">3:50</td>
      <td data-label="Maghrib">6:44</td>
      <td data-label="Isha">8:00</td>
    </tr>

    <tr>
      <td class="Date" data-label="Date">14-04-2021</td>
      <td data-label="Day">Wednesday</td>
      <td data-label="Ramadan">2</td>
      <td data-label="April/May">14</td>
      <td data-label="Imsak">4:28</td>
      <td data-label="Fajr">4:38</td>
      <td data-label="Sunrise">5:54</td>
      <td data-label="Dhuhr">12:22</td>
      <td data-label="Asr">3:49</td>
      <td data-label="Maghrib">6:44</td>
      <td data-label="Isha">8:01</td>
    </tr>
    
    <tr>
      <td class="Date" data-label="Date">15-04-2021</td>
      <td data-label="Day">Thursday</td>
      <td data-label="Ramadan">3</td>
      <td data-label="April/May">15</td>
      <td data-label="Imsak">4:27</td>
      <td data-label="Fajr">4:37</td>
      <td data-label="Sunrise">5:53</td>
      <td data-label="Dhuhr">12:22</td>
      <td data-label="Asr">3:49</td>
      <td data-label="Maghrib">6:45</td>
      <td data-label="Isha">8:01</td>
    </tr>
  </tbody>
</table>

<td class="Date" data-label="Date">13-04-2021</td> is a hidden column only used for scroll calculation. This could be the reason as pointed out in one of the solutions by Juan.

Answer

If there is no data that matches, the jquery returns a collection with .length === 0 – attempting .offset() on this gives undefined, and undefined.top will give an error.

Check if there is a matching date before calling offset() on it.

Note also that *:contains() will return all of the parent nodes as well. You should use a more specific selector.

In your example, use:

$("table.ramadan-time > tbody td.Date:contains('<%=ScrollDate%>')")

adding that with a check gives:

var cell = $("table.ramadan-time > tbody td.Date:contains('<%=ScrollDate%>')");
if (cell.length > 0) {
    $(window).scrollTop(cell.parent('tr').offset().top - 40);
}

$("#b1").click(() => {
  var cell = $("table.ramadan-time > tbody td.Date:contains('31-12-2099')");
  if (cell.length > 0) {
    $(window).scrollTop(cell.parent('tr').offset().top - 40);
  }
});

$("#b2").click(() => {
  var cell = $("table.ramadan-time > tbody td.Date:contains('31-12-2099')");
  $(window).scrollTop(cell.parent('tr').offset().top - 40);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="ramadan-time table-wrapper-scroll-x my-custom-scrollbar">
  <thead>
    <tr>
      <th scope="col">Date</th>
      <th scope="col">Day</th>
      <th scope="col">Ramadan</th>
      <th scope="col">April/May</th>
      <th scope="col">Imsak</th>
      <th scope="col">Fajr</th>
      <th scope="col">Sunrise</th>
      <th scope="col">Dhuhr</th>
      <th scope="col">Asr</th>
      <th scope="col">Maghrib</th>
      <th scope="col">Isha</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td class="Date" data-label="Date">13-04-2021</td>
      <td data-label="Day">Tuesday</td>
      <td data-label="Ramadan">1</td>
      <td data-label="April/May">13</td>
      <td data-label="Imsak">4:29</td>
      <td data-label="Fajr">4:39</td>
      <td data-label="Sunrise">5:55</td>
      <td data-label="Dhuhr">12:22</td>
      <td data-label="Asr">3:50</td>
      <td data-label="Maghrib">6:44</td>
      <td data-label="Isha">8:00</td>
    </tr>
    <tr>
      <td class="Date" data-label="Date">14-04-2021</td>
      <td data-label="Day">Wednesday</td>
      <td data-label="Ramadan">2</td>
      <td data-label="April/May">14</td>
      <td data-label="Imsak">4:28</td>
      <td data-label="Fajr">4:38</td>
      <td data-label="Sunrise">5:54</td>
      <td data-label="Dhuhr">12:22</td>
      <td data-label="Asr">3:49</td>
      <td data-label="Maghrib">6:44</td>
      <td data-label="Isha">8:01</td>
    </tr>

    <tr>
      <td class="Date" data-label="Date">15-04-2021</td>
      <td data-label="Day">Thursday</td>
      <td data-label="Ramadan">3</td>
      <td data-label="April/May">15</td>
      <td data-label="Imsak">4:27</td>
      <td data-label="Fajr">4:37</td>
      <td data-label="Sunrise">5:53</td>
      <td data-label="Dhuhr">12:22</td>
      <td data-label="Asr">3:49</td>
      <td data-label="Maghrib">6:45</td>
      <td data-label="Isha">8:01</td>
    </tr>

  </tbody>
</table>

<hr/>

<button type="button" id="b1">no error when not found</button>
<button type="button" id="b2">original, error when not found</button>