TypeError: dataTable.addRows is undefined in Charts.newDataTable()

I’m encountering a very strange issue in Google Apps Script and I’m hoping someone can shed some light on it. I’m getting a TypeError: dataTable.addRows is not a function when trying to build a DataTable for charts using Charts.newDataTable().

Here’s a minimal code snippet that reproduces the issue:

function testDataTable() {
  var dataTable = Charts.newDataTable();
  Logger.log(typeof dataTable.addColumn); // Output: "function"
  Logger.log(typeof dataTable.addRows);   // Output: "undefined"
}

As you can see, addColumn seems to be available, but addRows is unexpectedly undefined. This is preventing me from creating any charts.

My environment:

  • Google Account Type: Personal (@gmail.com)
  • Script Location: Testing in both a script bound to a Google Sheet and a standalone script.

Steps I’ve tried:

  • Double-checking the syntax for creating the DataTable.
  • Trying different ways to chain the methods.
  • Testing the minimal code above in a brand new Apps Script project.
    The issue persists even in a new project, with addRows consistently being reported as undefined.

Has anyone else experienced this issue, or does anyone have any insights into why addRows might be missing from the Charts.newDataTable() object?

React form time validation not working – alert not showing when start time is later than end time [duplicate]

`I’m working on a scheduling feature in a React project where teachers can update their available hours. The form includes start time and end time fields. My goal is to show an alert if the start time is greater than or equal to the end time, but the alert doesn’t show when I input an invalid range (e.g. start time 11:00, end time 10:00).

Here is my handleSubmit function logic

const handleSubmit = async (e) => {`
    e.preventDefault();
    if (!formData.startTime || !formData.endTime) {
      alert("Please select both start and end time.");
      return;
    }

    try {
      const startTimeStr = formData.startTime.padEnd(5, ":00").slice(0, 5);
      const endTimeStr = formData.endTime.padEnd(5, ":00").slice(0, 5);
      if (startTimeStr >= endTimeStr) {
        alert("Start time must be earlier than end time");
        return;
      }

      const updatedData = {
        date: formData.date,
        day: formData.day,
        startTime: formData.startTime,
        endTime: formData.endTime,
      };

      await updateAvailhours(selectedHour._id, updatedData);

      fetchAvailableHours();

      setIsModalOpen(false);
      alert("Available hour updated successfully!");
    } catch (error) {
      console.error("Update failed:", error);
      alert(
        "Failed to update. " + (error.response?.data?.message || "Try again.")
      );
    }
  };

Despite this logic, when I enter startTime = “11:00” and endTime = “10:00”, it doesn’t show the alert or stop the form submission. The form proceeds as if everything is valid.

Logging startMinutes and endMinutes values — they appear correct.
Wrapping the logic in try…catch — no error is thrown.
Checking input values manually in the UI — the values are correctly typed.
Ensuring no required attribute interferes with validation (still happens).

Why the startMinutes >= endMinutes condition is not stopping the form.
Whether e.preventDefault() is being bypassed.
A better way to handle this kind of time validation in React forms.`

Object is not being deleted from array after interecting with input checkbox

I am trying to achieve the following:

When input checkbox is true:

  • Add object to sites array state and local storage

When input checkbox is false:

  • Delete object from sites array state and local storage

The problem I experience right now is my setSites state updating function is not removing the object from local storage or from sites state

Heres method I use to delete the object and also remove from local storage(suggested via React docs here)

const index = sites.findIndex((site) => site.url.includes(domain));
setSites(sites.filter((site, i) => index !== site[i]));

Heres full app.jsx where I run the above from handleLogs() function

import React, { useState, useEffect } from 'react';
import { createRoot } from 'react-dom/client';

const App = () => {
  const [sites, setSites] = useState([]);

  useEffect(() => {
    chrome.storage.local.get(['sites'], (res) => {
      if (res.sites) {
        setSites(res.sites);
        console.log(`Loaded from storage`, res.sites);
      }
    });
  }, []);

  useEffect(() => {
    chrome.storage.local.set({ sites });
    console.log('Saved to storage:', sites);
  }, [sites]);

  function handleLogs(event) {
    chrome.tabs.query({ active: true, lastFocusedWindow: true }, (tabs) => {
      const domain = tabs[0].url.split('/')[2];
      const fullURL = tabs[0].url;

      if (event.target.checked === false) {
        // remove current site from sites array
        const index = sites.findIndex((site) => site.url.includes(domain));
        setSites(sites.filter((site, i) => index !== site[i]));

        // store new sites in local storage
        chrome.storage.local.set({ sites });

        // remove ?tracking
        const newUrl = fullURL.replace('?tracking', '');
        chrome.tabs.update(tabs[0].id, { url: newUrl });
      } else {
        if (fullURL.includes('?tracking')) {
          console.log('Url already contains tracking');
          return;
        }

        // push new site to array and save to local storage
        setSites((prevSites) => [
          ...prevSites,
          { url: domain }
        ]);
        chrome.storage.local.set({ sites });

        // Decorate URL with parameter
        const params = encodeURI('tracking');
        const url = tabs[0].url;
        const hashStart =
          url.indexOf('#') === -1 ? url.length : url.indexOf('#');
        const querySymbol = url.indexOf('?') === -1 ? '?' : '&';
        var newUrl = `${url.substring(
          0,
          hashStart
        )}${querySymbol}${params}${url.substring(hashStart)}`;

        // Refresh page with new URL
        chrome.tabs.update(tabs[0].id, { url: newUrl });
      }
    });
  }

  return <input type="checkbox" onClick={(event) => handleLogs(event)} />;
};

const container = document.createElement('div');
document.body.appendChild(container);
const root = createRoot(container);
root.render(<App />);

A bit tricky to debug this in browser as Webpack process is outputting bundled file. Still working on it. But, what am I doing wrong here?

Where is the problem in the code?php,JavaScript,html [closed]

I can’t understand why my code doesn’t work. Values ​​are obtained from the database.

file Db_get.php:

<?php

function db_get (mixed $table_name) : mixed
{
    $db= new PDO('sqlite:db.db');
    $stmt=$db->prepare("SELECT * FROM `$table_name` ORDER BY 1 DESC LIMIT 1;");
    $stmt->execute();
    $table=$stmt->fetchall(PDO::FETCH_ASSOC);


    return $table;
}

file Form_1.php:

<?php
function form_function_1(mixed $unit_of_measurement, mixed $sensor_name, mixed $sensor_value){


if (isset($_GET['value1'])) {
    $value = $_GET['value1'];
} else {
    $value = $sensor_value;
}

if (isset($_GET['checkbox_value1'])) {
    $checkbox_value = $_GET['checkbox_value1'];
} else {
    $checkbox_value = '';
}
?>


<form method="GET" id="myForm1">
    <?php echo $sensor_name;
    echo "&nbsp;&nbsp;";
    echo $unit_of_measurement;

    ?>

    <input type="text" name="value1" value="<?php echo $value; ?>"
        <?php
        if (empty($checkbox_value)) {
            echo 'disabled';
        }
        ?>>

    <input type="checkbox" id="myCheckbox1" name="checkbox_value1" value="1"
        <?php
        if (!empty($checkbox_value)) {
            echo 'checked';
        }
        ?>>

    <input type="submit" value="Send" <?php if (empty($checkbox_value)){echo 'disabled';}?>>

</form>

<script>
    
    function sendForm() {
        document.getElementById("myForm1").submit();
    }

    
    document.querySelector('#myCheckbox1').addEventListener('change', function() {
        const inputValue = document.querySelector('input[name="value1"]');

        
        if (!this.checked) {
           
            inputValue.value = <?php echo $sensor_value; ?>;
            inputValue.disabled = true;
        } else {
    
            inputValue.disabled = false;
        }

        sendForm();
    });

   
    if (document.querySelector('#myCheckbox1').checked) {
        document.querySelector('input[name="value1"]').disabled = false;
    } else {
        document.querySelector('input[name="value1"]').disabled = true;
    }
</script>

    <?php
}
?>

file Form_2.php:

<?php
function form_function_2(mixed $unit_of_measurement, mixed $sensor_name, mixed $sensor_value){
if (isset($_GET['value2'])) {
    $value = $_GET['value2'];
} else {
    $value = $sensor_value;
}

if (isset($_GET['checkbox_value2'])) {
    $checkbox_value = $_GET['checkbox_value2'];
} else {
    $checkbox_value = '';
}
?>

        
<form method="GET" id="myForm2">
    <?php echo $sensor_name;
    echo "&nbsp;&nbsp;";
    echo $unit_of_measurement;

    ?>

    <input type="text" name="value2" value="<?php echo $value; ?>"
        <?php
        if (empty($checkbox_value)) {
            echo 'disabled';
        }
        ?>>

    <input type="checkbox" id="myCheckbox2" name="checkbox_value2" value="1"
        <?php
        if (!empty($checkbox_value)) {
            echo 'checked';
        }
        ?>>

    <input type="submit" value="Send" <?php if (empty($checkbox_value)){echo 'disabled';}?>>

</form>

<script>

    function sendForm() {
        document.getElementById("myForm2").submit();
    }

    document.querySelector('#myCheckbox2').addEventListener('change', function() {
        const inputValue = document.querySelector('input[name="value2"]');

        if (!this.checked) {
            
            inputValue.value = <?php echo $sensor_value; ?>;
            inputValue.disabled = true;
        } else {

            inputValue.disabled = false;
        }

        sendForm();
    });

    if (document.querySelector('#myCheckbox2').checked) {
        document.querySelector('input[name="value2"]').disabled = false;
    } else {
        document.querySelector('input[name="value2"]').disabled = true;
    }
</script>
<?php
}
?>

file Settings_start:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Settings</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
</head>
<body>
<?php
include "Form_1.php";
include "Form_2.php";
include "Db_get.php";
$table_Pressure=db_get('Pressure');
$table_Temperature=db_get('Temperature');

form_function_1($table_Pressure[0]['unit_of_measurement'],$table_Pressure[0]['sensor_name'],$table_Pressure[0]['value']);
form_function_2($table_Temperature[0]['unit_of_measurement'],$table_Temperature[0]['sensor_name'],$table_Temperature[0]['value']);
?>
</html>

For some reason, the function that is called first does not work correctly. I tried to rearrange the function call, but the problem is still in the function that is called first. The incorrect operation of the function is that when you select a checkbox, a request is sent (automatically) and the checkbox immediately ceases to be selected, accordingly the send button becomes unavailable, and you cannot enter anything into the form.
The problem is that the checkbox stops being selected.

I don’t know exactly what language the problem is.
But presumably JavaScript.
There were no error messages.
The problem occurs when calling functions form_function_1 and form_function_1.

How to set basename for react-router v7 framework mode?

I have created a React-Router framework mode app like this:

npx create-react-router@latest my-react-router-app

The version of React-Router is:

"react-router": "^7.5.1"

In routes.ts I have added a bunch of pages:

export default [
  index("routes/login.tsx"),
  route("menu", "routes/menu.tsx"),
  route("skills", "routes/skills.tsx"),
  route("courses", "routes/courses.tsx"),
] satisfies RouteConfig;

Everything is working just fine during development. Now, I need to deploy this app in the "/courses" folder of the web server’s document root (I have server side rendering disabled in react-router.config.ts). I cannot find any updated information on how to set the basename to "/courses". Most of the information seems outdated. How do I configure the basename in framework mode?

Why my js code doesn’t work? php, html, js [closed]

I can’t understand why my code doesn’t work. Values ​​are obtained from the database.

file Db_get.php:

<?php

function db_get (mixed $table_name) : mixed
{
    $db= new PDO('sqlite:db.db');
    $stmt=$db->prepare("SELECT * FROM `$table_name` ORDER BY 1 DESC LIMIT 1;");
    $stmt->execute();
    $table=$stmt->fetchall(PDO::FETCH_ASSOC);


    return $table;
}

file Form_1.php:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
</head>
<body>
<?php

function form_function_1(mixed $unit_of_measurement, mixed $sensor_name, mixed $sensor_value){

if (isset($_GET['value1'])) {
    $value = $_GET['value1'];
} else {
    $value = $sensor_value;
}

if (isset($_GET['checkbox_value1'])) {
    $checkbox_value = $_GET['checkbox_value1'];
} else {
    $checkbox_value = '';
}
?>

<form method="GET" id="myForm1">
    <?php echo $sensor_name;
        echo "&nbsp;&nbsp;";
        echo $unit_of_measurement;
    ?>

    <input type="text" name="value1" value="<?php echo $value; ?>"
        <?php
            if (empty($checkbox_value)) {
                echo 'disabled';
            }
        ?>>

    <input type="checkbox" id="myCheckbox1" name="checkbox_value1" value="1"
        <?php
            if (!empty($checkbox_value)) {
                echo 'checked';
            }
        ?>>

    <input type="submit" value="Send" <?php if (empty($checkbox_value)){echo 'disabled';}?>>

</form>

<script>
    function sendForm() {
        document.getElementById("myForm1").submit();
    }

    document.querySelector('#myCheckbox1').addEventListener('change', function() {
        const inputValue = document.querySelector('input[name="value1"]');

        
        if (!this.checked) { 
            inputValue.value = <?php echo $sensor_value; ?>;
            inputValue.disabled = true;
        } else {
            inputValue.disabled = false;
        }
        sendForm();
    });

    
    if (document.querySelector('#myCheckbox1').checked) {
        document.querySelector('input[name="value1"]').disabled = false;
    } else {
        document.querySelector('input[name="value1"]').disabled = true;
    }
</script>

</body>
</html>
<?php
}
?>

file Form_2.php:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
</head>
<body>
<?php


function form_function_2(mixed $unit_of_measurement, mixed $sensor_name, mixed $sensor_value){
        
if (isset($_GET['value2'])) {
    $value = $_GET['value2'];
} else {
    $value = $sensor_value;
}

if (isset($_GET['checkbox_value2'])) {
    $checkbox_value = $_GET['checkbox_value2'];
} else {
    $checkbox_value = '';
}
?>

<form method="GET" id="myForm2">
    <?php echo $sensor_name;
        echo "&nbsp;&nbsp;";
        echo $unit_of_measurement;
    ?>

    <input type="text" name="value2" value="<?php echo $value; ?>"
        <?php
            if (empty($checkbox_value)) {
                echo 'disabled';
            }
        ?>>

    <input type="checkbox" id="myCheckbox2" name="checkbox_value2" value="1"
        <?php
            if (!empty($checkbox_value)) {
                echo 'checked';
            }
        ?>>

    <input type="submit" value="Send" <?php if (empty($checkbox_value)){echo 'disabled';}?>>

</form>

<script>
    function sendForm() {
        document.getElementById("myForm2").submit();
    }

    document.querySelector('#myCheckbox2').addEventListener('change', function() {
        const inputValue = document.querySelector('input[name="value2"]');

        if (!this.checked) {
            inputValue.value = <?php echo $sensor_value; ?>;
            inputValue.disabled = true;
        } else {
            inputValue.disabled = false;
        }

        sendForm();
    });

    if (document.querySelector('#myCheckbox2').checked) {
        document.querySelector('input[name="value2"]').disabled = false;
    } else {
        document.querySelector('input[name="value2"]').disabled = true;
    }
</script>

</body>
</html>
<?php
}
?>

file Settings_start:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Settings</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
</head>
<body>
<?php
include "Form_1.php";
include "Form_2.php";
include "Db_get.php";
$table_Pressure=db_get('Pressure');
$table_Temperature=db_get('Temperature');

form_function_1($table_Pressure[0]['unit_of_measurement'],$table_Pressure[0]['sensor_name'],$table_Pressure[0]['value']);
form_function_2($table_Temperature[0]['unit_of_measurement'],$table_Temperature[0]['sensor_name'],$table_Temperature[0]['value']);
?>
</html>

For some reason, the function that is called first does not work correctly. I tried to rearrange the function call, but the problem is still in the function that is called first. The incorrect operation of the function is that when you select a checkbox, a request is sent (automatically) and the checkbox immediately ceases to be selected, accordingly the send button becomes unavailable, and you cannot enter anything into the form.
There were no error messages.

Reloading with frequent clicking on the Profile button

When I click on the profile link multiple times, the page keeps reloading and sending lots of requests before finally redirecting to the profile. How can I prevent the page from reloading and make it instantly follow the link??
I tried switch <a> on <Link> next js, but i’m not sure if CSS styling will be affected.

const NavProfile = () => (
        <>
            <NavbarLink href="/profile">
                <UIIcon
                    name="card"
                    className={styles.iconCard}
                />
                Основное
            </NavbarLink>
            
}

export const NavbarLink = ({ href, children, css, activePaths = [], target }) => (
    <li>
        <ActiveLink
            activePaths={activePaths}
            href={href}
            css={css}
            target={target}>
            {children}
        </ActiveLink>
    </li>
);
function ActiveLink({
    css,
    href,
    onClick,
    nofollow,
    includedPath,
    children,
    className,
    activePaths = [],
    changeLocation = true,
    allowAllPathsToBeActive,
    target
}) {
    const router = useRouter();

    const handleClick = e => {
        if (target !== "_blank") {
            e.preventDefault();

            if (onClick) onClick(e);

            if (changeLocation) router.push(href);
        }
    };

    const pathIncludesHref = (path, href) => {
        return (
            path.split("?")[0] === href ||
            path.split("#access_token")[0] === href ||
            path.split("access_token")[0] === href
        );
    };

    let active = "false";

    let path = router.asPath.split("/");
    if (path[path.length - 1] === "#") {
        path.pop();
    }
    path = path.join("/");
    path = path ? path : "/";

    if (
        pathIncludesHref(path, href) ||
        activePaths.includes(path) ||
        (allowAllPathsToBeActive && path.indexOf(href) !== -1) ||
        (includedPath && path.split("?")[0].includes(includedPath))
    ) {
        active = "true";
    }

    return (
        <a href={href} className={className} onClick={handleClick}
            active={active}
            target="_blank"
            style={css}>
            {children}
        </a>
    );
}

Why is this RxJS subscription never closed?

I have suspected memory leaks and stale RxJS subscriptions for a while in corporate software. I decided to investigate by writing the snippet below. It’s very simple. First, it loads RxJS. Second, it monkey patches Observable’s subscribe method in order to spy on it and monitor what’s going on. Third, I create the following subscription:

rxjs.interval(1_000).pipe(rxjs.take(3)).subscribe()

It’s just an Observable which emits one value every second and stop after three values. My monkey patched subscribe method reveals a few things. One of them is that this is not one subscription but two. Not very surprising, we have a pipe and so each operator (here only take(3)) will create an Observable subscribing to the previous one (here internal(1_000)).

But it reveals another much more surprising fact. After the three values have been emitted, one subscription is closed but not the other. It looks like the “source”, so interval(1_000), remains active forever. You can try for yourself using the snippet below. You will see both subscriptions printing the first three values to the console and then only one of them remains and keeps printing without stopping. I would expect both subscriptions to be closed. Why is it not the case?

// This script monkey patches Observable's subscribe method to spy on it

let subscriptionCount = 0;

const observables = [];
const subscriptions = [];
const values = [];

const originalSubscribe = rxjs.Observable.prototype.subscribe;

Error.stackTraceLimit = Infinity;

rxjs.Observable.prototype.subscribe = function(observerOrNext, error, complete) {
    if (!this.id) {
        this.id = observables.length;
        observables.push(this);
    }

    const subscriptionId = subscriptionCount++;

    const interceptValue = value => {
        console.log(`Subscription ${subscriptionId}: ${value}`);

        values[subscriptionId] = values[subscriptionId] || [];
        values[subscriptionId].push(value);

        if (subscriptions[subscriptionId]) {
            subscriptions[subscriptionId].lastValueDate = Date.now();
        }
    };

    let observer;
    if (typeof observerOrNext === 'function') {
        observer = value => {
            interceptValue(value);
            observerOrNext(value);
        };
    } else {
        observer = {
            next: value => {
                interceptValue(value);
                observerOrNext?.next?.(value);
            },
            error: err => {
                observerOrNext?.error?.(err);
            },
            complete: () => {
                observerOrNext?.complete?.();
            }
        };
    }

    const subscription = originalSubscribe.call(this, observer, error, complete);
    subscription.id = subscriptionId;
    subscription.observableId = this.id;
    subscription.creationDate = Date.now();
    subscription.trace = new Error().stack;
    subscriptions.push(subscription);

    return subscription;
}

// Here is the actual MRE

rxjs.interval(1_000).pipe(rxjs.take(3)).subscribe();
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/7.8.2/rxjs.umd.js"></script>

viewer._pages unexpectedly becomes empty in PDF.js PDFViewer instance

I’m integrating pdfjs-dist’s PDFViewer in a React project using the pdfjs-dist/web/pdf_viewer module. Everything works fine initially — the PDF loads, the pages render, and I’m able to interact with them.

However, at some point later in the flow, I’m noticing that viewer._pages (which initially holds all page references) becomes unexpectedly empty ([]). This is causing issues with a custom updateVisiblePages function I wrote to hide/show certain pages based on user interaction.

const updateVisiblePages = useCallback(
        (viewer: any) => {
            console.log(viewer, 'viewer updateVisiblePages before return')

            if (!viewer || !viewer._pages.length) return
            console.log(viewer, 'after return')
            const allPages = viewer._pages
            let updated = false
            allPages.length !== 0 &&
                allPages.forEach((page: any, index: number) => {
                    const pageNum = index + 1
                    if (!isSearchActive) {
                        if (
                            pageNum < (Number(selectedContent.startPage) ?? 1) ||
                            pageNum > (Number(selectedContent.endPage) ?? allPages.length)
                        ) {
                            if (!page.div.classList.contains('hidden-page')) {
                                page.div.classList.add('hidden-page') // Add class to hide
                                updated = true
                            }
                        } else {
                            if (page.div.classList.contains('hidden-page')) {
                                page.div.classList.remove('hidden-page') // Remove class to show
                                updated = true
                            }
                        }
                    } else {
                        if (page.div.classList.contains('hidden-page')) {
                            console.log(
                                '[DEBUG] Pages updated, removing hidden-page class when searching',
                            )
                            page.div.classList.remove('hidden-page') // Remove class to show
                            updated = true
                        }
                    }
                })

            if (updated) {
                viewer.update() // Ensure the viewer updates its rendering
                setVisiblePagesUpdated((prev) => !prev) // Trigger re-render
                updateHeight()
                window.addEventListener('resize', updateHeight)
                return () => window.removeEventListener('resize', updateHeight)
            }
        },
        [selectedContent, isSearchActive],
    )

And I’m setting up the viewer like this inside a useEffect:

const viewer = new PDFViewer({
    container: container,
    eventBus: eventBusInstance,
    enableWebGL: true,
    renderInteractiveForms: true,
    textLayerMode: 2,
    enhanceTextSelection: true,
});

viewer.setDocument(pdfDoc);

My questions:

What can cause viewer._pages to become empty after the PDF is loaded?

Is there a lifecycle method or event I should hook into to prevent accessing _pages at the wrong time?

Is there a better/official API for tracking rendered pages instead of relying on _pages (which I realize is a private field)?

Any help in understanding when or why _pages gets reset/cleared would be greatly appreciated!

I am having problems in integrating laravel with react should i keep on trying or shift the backend? [closed]

So I am having problems in integrating laravel with react there are only two errors that pop up with no solution even from chatgpt its either

  1. 404 | Not Found
  2. A blank page with the following lines in the terminal
    SyntaxError: Unexpected token ‘<‘, “<!DOCTYPE “… is not valid JSON

What should I do because at this point I have tried everything….

Every possible solution I could find

How can I execute a SQL-Select-Statement against a table in memory in SQL.js?

I use SQL.js and I need a solution in this framework.

I want to execute a SELECT-Statement against a table I retrieved from the database. Is there any way to achieve this?

I tried so far:

let table = db.exec("select * from Person")[0];
let res = db.exec("select * from @table", {"@table": table});

I’m aware that I could simply write db.exec("select * from Person") in this special case, but this is a simplified example. In my use case I get the table from another source.

How to create a trusted event of dragging a file into a drag-zone input using Playwright

In a Playwright test, I have an input field that is marked as a drag-and-drop zone for files that I want to test our logic on.

When trying to use Playwright’s page.dispatchEvent of drop, the created event has the value of isTrusted === false which is bad for me. Here’s a typescript example:

const buffer = readFileSync('file.txt')
const dataTransfer = await page.evaluateHandle(async (data) => {
    const dt = new DataTransfer();
    const file = new File([data], 'file.txt', { type: 'text/plain' })
    dt.items.add(file)
    return dt
}, buffer)

await page.dispatchEvent("#drag-area", "drop", { dataTransfer });

Another attempt was to use locator.dragTo from a custom element, but I couldn’t manage to add my file to the items.dataTransfer object – the element’s event listener did not contain my file after adding to event.dataTransfer.items

(This is a follow-up to this question: How to drag a file to a drag-zone input element using Playwright.
I have also checked out the Playwright issue about this to no avail: https://github.com/microsoft/playwright/issues/10667#issuecomment-998397241)

So, my question is, how do I create a drag-file event in Playwright with the property event.isTrusted=true and with a custom file?

Question to behavior of JS addEventListener (Seems to double fire)

I was looking to open a dropdown by button-click and close it when there is a click anywhere in the DOM (except dropdown). Now for some reason the way i was trying that did result in the event firing apparently twice. I was wondering why? Here’s some code with the core problem:

<!DOCTYPE html>
<html lang="">
  <head>
  </head>
  <body>
    <button id="btn">ABC</span>
  </body>
  <script>
    document.getElementById("btn").addEventListener("click", () => {
      console.log("fire");
      document.getElementsByTagName("body")[0].addEventListener("click", () => {
        console.log("fire");
      });
    });
  </script>
</html>