Skip to content

Commit

Permalink
Fix: Allow multiple dynamic Stimulus controllers on a single element
Browse files Browse the repository at this point in the history
Given the following setup:

```html
<div data-controller="a-controller b-controller"
     data-application-target="dynamic">
  <!-- More HTML -->
</div>
```

We'd run into the following console error:

```
op-application.controller.ts:18 Failed to load dyanmic controller chunk user-limit work-packages--share--user-selected: Error: Cannot find module './user-limit work-packages/share/user-selected.controller'
```

This is because the way the handling for dynamic controllers currently
only supports a single controller at a time, causing
"a-controller b-controller" to be interpreted as a single Stimulus
controller.

My intent with this commit is to be able to have multiple dynamic
Stimulus controllers driving an element and therefore "a-controller"
AND "b-controller" being loaded as the individual controllers they are.
  • Loading branch information
aaron-contreras committed Nov 30, 2023
1 parent b7e402b commit bb4ef1c
Showing 1 changed file with 13 additions and 10 deletions.
23 changes: 13 additions & 10 deletions frontend/src/stimulus/controllers/op-application.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,20 @@ export class OpApplicationController extends ApplicationController {
private loaded = new Set<string>();

dynamicTargetConnected(target:HTMLElement) {
const controller = target.dataset.controller as string;
const path = this.derivePath(controller);
const controllers = (target.dataset.controller as string).split(' ');

if (!this.loaded.has(controller)) {
this.loaded.add(controller);
void import(/* webpackChunkName: "[request]" */`./dynamic/${path}.controller`)
.then((imported:{ default:ControllerConstructor }) => this.application.register(controller, imported.default))
.catch((err:unknown) => {
console.error('Failed to load dyanmic controller chunk %O: %O', controller, err);
});
}
controllers.forEach((controller) => {
const path = this.derivePath(controller);

if (!this.loaded.has(controller)) {
this.loaded.add(controller);
void import(/* webpackChunkName: "[request]" */`./dynamic/${path}.controller`)
.then((imported:{ default:ControllerConstructor }) => this.application.register(controller, imported.default))
.catch((err:unknown) => {
console.error('Failed to load dyanmic controller chunk %O: %O', controller, err);
});
}
});
}

/**
Expand Down

0 comments on commit bb4ef1c

Please sign in to comment.