-
-
Notifications
You must be signed in to change notification settings - Fork 340
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[LiveComponent] getComponent is undefined if the controller loads very quickly as explained in the docs #1544
Comments
Any update or workaround? Still in the official documentation... |
Instead of using connect there, you should rely on the events dispatched by the LiveComponent |
What do you mean @smnandre ? It's the official example in Symfony docs! |
The documentation is see // assets/controllers/some-custom-controller.js
// ...
import { getComponent } from '@symfony/ux-live-component';
export default class extends Controller {
async initialize() {
this.component = await getComponent(this.element);
this.component.on('render:finished', (component) => {
// do something after the component re-renders
});
}
} |
And it's a bit... skinny. What if I need component.emit based on some javascript event? Where would you put that logic? onPaste() {
this.component.emitSelf("paste", { value });
} Inside |
async initialize() {
this.component = await getComponent(this.element);
// THERE
this.component.on('render:finished', (component) => {
// do something after the component re-renders
});
} |
Thank you for this issue. |
I have this problem in another project, again 😢 The
In my custom Stimulus controller: async connect() {
this.component = await getComponent(this.element);
this.activate();
} The component is rendered as: <div data-controller="barcode-scanner live"></div> Could be an issue related to the fact that MY controller is listed before the live controller (as you can see from the screeshot below)? From the source, I can see that getComponent` will try 10 times every 5ms, for a total time of 500ms. |
Is one of your controllers fetched lazily ? |
Hello, I have the exact same issue, and it also happens only "from time to time". I understand this inconsistency is because of the interval inside live_controller.js : // vendor/symfony/ux-live-component/assets/dist/live_controller.js (l.144) :
const getComponent = (element) => new Promise((resolve, reject) => {
let count = 0;
const maxCount = 10;
const interval = setInterval(() => {
const component = componentMapByElement.get(element);
if (component) {
clearInterval(interval);
resolve(component);
}
count++;
if (count > maxCount) {
clearInterval(interval);
reject(new Error(`Component not found for element ${getElementAsTagText(element)}`));
}
}, 5);
}); So, sometimes the component can be found before the tenth attempt, sometimes it can't... but why? I can't figure out the reason. The easiest way for me to reproduce the error is by continuously switching from page A to page B then page B to page A (with both pages using the same component - not sure if that's relevant). By doing this on a remote test server, the error happens at almost each page change (like 99% of the time or so). But somehow when I do the same on my local machine, the error is much less frequent (but still there "from time to time" though). Now I'm just randomly guessing but : could this be related to Turbo? Like when Turbo temporarily shows the previously cached version of page A while loading its refreshed version. I mean something like that :
That's just a suggestion based on my own observations, but I'm really sure about nothing here. Like I said I'm just guessing, it's very hard to understand what exactly happens. |
I can't reproduce either when/why we get undefined when calling getComponent. I can only quote myself:
As a workaround right now I'm doing: const component = this.element.__component ?? (await getComponent(this.element)); ... right before calling my (remote) action from the controller. |
I really would like to help but i don't have enough time right no, so with no reproducer you understand it can be hard. If i had more time i'd do more but right now i fear i won't be usefull here :| |
Still having this problem after nearly one year 😢 😢 😢 This is in production. Nearly every time I click very quickly on the stamp icon (where the component uses Standard code from Symfony UX live docs: export default class extends Controller {
component;
async initialize() {
this.component = await getComponent(this.element);
}
} Maybe this
|
Based on the docs the
getComponent
method should be called duringinitialize
. Becase it's aPromise
the methodinitialize
should beasync
.When the component loads very quickly,
this.component
will be undefined inconnect
:Adding
async connect
won't solve the problem. Adding a small delay will solve the problem. Another way is to callgetComponent
insideasync connect
. Either way, the documentation is a bit "obscure" about this and devs without a good JavaScript understanding will have the same issue.I don't know if this is a bug or the way Stimulus work, but I was expecting that
connect
will be called afterinitialize
resolve.The text was updated successfully, but these errors were encountered: