orchidsoftware / platform

Orchid is a @laravel package that allows for rapid application development of back-office applications, admin/user panels, and dashboards.
https://orchid.software
MIT License
4.26k stars 631 forks source link

In Listener, old listener_controller event is still being triggered on target field change #2794

Open nayminlwin opened 5 months ago

nayminlwin commented 5 months ago

Describe the bug When using Listener with target field and then changing the target field more than once will trigger the old controller instance's asyncLoadData function. This causes the browser to throw an error FormData constructor: Argument 1 is not an object. since the controller's element is already detached.

To Reproduce Steps to reproduce the behavior:

  1. Create a Screen with a single checkbox
  2. Create a Listener that targets the checkbox
  3. Check/uncheck the checkbox more than once

Expected behavior No client side error occurred.

Desktop (please complete the following information):

Server (please complete the following information):

Additional context Seems like the problem's caused by stale event handler pointing to the asyncLoadData. I tried removing the event handler on disconnect to solve it through my own custom controller like follows.

    eventHandles = {};
    connect() {
        this.targets.forEach(name => {
            document.querySelectorAll(`[name="${name}"]`)
                .forEach((field) => {
                    this.eventHandles[field] = () => this.asyncLoadData();
                    field.addEventListener('change',  this.eventHandles[field])
                });
        });
    }
    disconnect() {
        this.targets.forEach(name => {
            document.querySelectorAll(`[name="${name}"]`)
                .forEach((field) =>
                    field.removeEventListener('change', this.eventHandles[field])
                );
        });
    }

Not sure if this is the preferred approach though. If so, I can submit a pull request.