Turbo Frame event listener duplicate firing

Hi,

I’m using Turbo Frames to poll status for background activejobs (I know most would recommend Turbo Streams for this purpose.). Each event fires once for each of the active turbo frames that are polling. My goal and intention is to remove the duplicate event firing so that the polling is efficient. I would appreciate if someone could explain why the duplicate event firing is occurring. I’m not understanding something crucial in the way the event listener or javascript is running here. Thank you.

Here is the relevant javascript:

<script type="text/javascript">
  $(document).ready(function() {
    document.addEventListener("turbo:frame-load", checkJobStatus, true);
  });
  async function checkJobStatus() {

    let job_id = event.target.getAttribute('id');
    let frame = document.getElementById(job_id);
    console.log('event: ' + job_id);
    console.log(event.target);

      if (frame !== null && event.target.getElementsByTagName('div') !== null && event.target.getElementsByTagName('div')[0].getAttribute('id') !== 'job-completed') {
        console.log('sleeping: ' + job_id);
        await sleep(10000);
        frame.reload();
      }
  }
  function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

And here is the output when I have 3 frames polling their job statuses (likewise you would see each event fire 4 times if there were 4 frames polling):

10:01:33.401 VM13:13 <turbo-frame id=​"job_c72f2cb1-10eb-4e5b-abf2-8d676e214149" src=​"/​report_job_status?job_id=c72f2cb1-10eb-4e5b-abf2-8d676e214149&report_id=101">​<div id=​"job-unknown">​Not Processed 18:01:17​​​
10:01:33.401 VM13:18 sleeping: job_c72f2cb1-10eb-4e5b-abf2-8d676e214149
10:01:33.401 VM39:12 event: job_c72f2cb1-10eb-4e5b-abf2-8d676e214149
10:01:33.402 VM39:13 <turbo-frame id=​"job_c72f2cb1-10eb-4e5b-abf2-8d676e214149" src=​"/​report_job_status?job_id=c72f2cb1-10eb-4e5b-abf2-8d676e214149&report_id=101">​<div id=​"job-unknown">​Not Processed 18:01:17​​​
10:01:33.402 VM39:18 sleeping: job_c72f2cb1-10eb-4e5b-abf2-8d676e214149
10:01:33.402 VM164:12 event: job_c72f2cb1-10eb-4e5b-abf2-8d676e214149
10:01:33.402 VM164:13 <turbo-frame id=​"job_c72f2cb1-10eb-4e5b-abf2-8d676e214149" src=​"/​report_job_status?job_id=c72f2cb1-10eb-4e5b-abf2-8d676e214149&report_id=101">​<div id=​"job-unknown">​Not Processed 18:01:17​​​
10:01:33.402 VM164:18 sleeping: job_c72f2cb1-10eb-4e5b-abf2-8d676e214149
10:01:33.402 VM13:12 event: job_cc230624-25c1-4912-9c69-9f9230d29818
10:01:33.403 VM13:13 <turbo-frame id=​"job_cc230624-25c1-4912-9c69-9f9230d29818" src=​"/​report_job_status?job_id=cc230624-25c1-4912-9c69-9f9230d29818&report_id=100">​<div id=​"job-unknown">​Not Processed 18:01:19​​​
10:01:33.403 VM13:18 sleeping: job_cc230624-25c1-4912-9c69-9f9230d29818
10:01:33.403 VM39:12 event: job_cc230624-25c1-4912-9c69-9f9230d29818
10:01:33.403 VM39:13 <turbo-frame id=​"job_cc230624-25c1-4912-9c69-9f9230d29818" src=​"/​report_job_status?job_id=cc230624-25c1-4912-9c69-9f9230d29818&report_id=100">​<div id=​"job-unknown">​Not Processed 18:01:19​​​
10:01:33.403 VM39:18 sleeping: job_cc230624-25c1-4912-9c69-9f9230d29818
10:01:33.403 VM164:12 event: job_cc230624-25c1-4912-9c69-9f9230d29818
10:01:33.403 VM164:13 <turbo-frame id=​"job_cc230624-25c1-4912-9c69-9f9230d29818" src=​"/​report_job_status?job_id=cc230624-25c1-4912-9c69-9f9230d29818&report_id=100">​<div id=​"job-unknown">​Not Processed 18:01:19​​​
10:01:33.403 VM164:18 sleeping: job_cc230624-25c1-4912-9c69-9f9230d29818
10:01:33.404 VM13:12 event: job_ff8ebcaa-096b-4357-b887-6cf5fd42ce2d
10:01:33.404 VM13:13 <turbo-frame id=​"job_ff8ebcaa-096b-4357-b887-6cf5fd42ce2d" src=​"/​report_job_status?job_id=ff8ebcaa-096b-4357-b887-6cf5fd42ce2d&report_id=102">​<div id=​"job-queued">​Queued 18:01:21​​​
10:01:33.404 VM13:18 sleeping: job_ff8ebcaa-096b-4357-b887-6cf5fd42ce2d
10:01:33.405 VM39:12 event: job_ff8ebcaa-096b-4357-b887-6cf5fd42ce2d
10:01:33.405 VM39:13 <turbo-frame id=​"job_ff8ebcaa-096b-4357-b887-6cf5fd42ce2d" src=​"/​report_job_status?job_id=ff8ebcaa-096b-4357-b887-6cf5fd42ce2d&report_id=102">​<div id=​"job-queued">​Queued 18:01:21​​​
10:01:33.405 VM39:18 sleeping: job_ff8ebcaa-096b-4357-b887-6cf5fd42ce2d
10:01:33.406 VM164:12 event: job_ff8ebcaa-096b-4357-b887-6cf5fd42ce2d
10:01:33.406 VM164:13 <turbo-frame id=​"job_ff8ebcaa-096b-4357-b887-6cf5fd42ce2d" src=​"/​report_job_status?job_id=ff8ebcaa-096b-4357-b887-6cf5fd42ce2d&report_id=102">​<div id=​"job-queued">​Queued 18:01:21​​​
10:01:33.406 VM164:18 sleeping: job_ff8ebcaa-096b-4357-b887-6cf5fd42ce2d

Typo in the code?

- async function checkJobStatus() {
+ async function checkJobStatus(event) {

I might also test to confirm the code only creates one event listener:

$(document).ready(function() {
+ console.log('addEventListener turbo:frame-load -> checkJobStatus');
  document.addEventListener("turbo:frame-load", checkJobStatus, true);
});

Thank you, tleish. Adding the event parameter to the checkJobStatus() function signature fixed this issue.

Everything will be Turbo.