Home > Software engineering >  New Symfony UX Live Components work but aren't updated interactively
New Symfony UX Live Components work but aren't updated interactively

Time:10-26

I've been asked by a client to look into Symfony UX's Live Components for use in an internal project. We/they are away of its alpha status and the fact that it will likely change and break over time so no need to point that out.

The thing is: I got everything working but the Live Components just act like regular Twig Components that don't actually update interactively without a refresh of the page. I've gone so far as to literally take an example from the documentation in an attempt to get it running, but it just won't update. Is anyone familiar with these components able to point out what I might have done wrong?

First off, I've included the component in Composer:

    "require": {
        ...
        "symfony/ux-live-component": "^2.4",
        ...
    }

package.json contains the required stuff as well:

    "devDependencies": {
        ...
        "@hotwired/stimulus": "^3.0.0",
        "@symfony/stimulus-bridge": "^3.2.0",
        "@symfony/ux-live-component": "file:vendor/symfony/ux-live-component/assets",
        ...
    }

The Stimulus bridge is enabled in my webpack config:

Encore.enableStimulusBridge('./assets/controllers.json')

And I've included its bootstrap file in my main JS file:

import './bootstrap';

Finally I made this component and template:

<?php

declare(strict_types=1);

namespace App\Component;

use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
use Symfony\UX\LiveComponent\Attribute\LiveProp;
use Symfony\UX\LiveComponent\DefaultActionTrait;

#[AsLiveComponent('random_number')]
class RandomNumberComponent
{
    use DefaultActionTrait;

    #[LiveProp(writable: true)]
    public int $max = 1000;

    public function getRandomNumber(): int
    {
        return rand(0, $this->max);
    }
}
<div {{ attributes }}>
    <p>Random number: <strong>{{ this.randomNumber }}</strong></p>
    <p>Generating a number between 0 and {{ max }}</p>

    <div >
        <label>Max</label>
        <input  type="number" data-model="max">
    </div>

    <button data-action="live#$render" >Generate a new number!</button>
</div>

Clicking the button or changing the value of the input has no effect. When I refresh the page I do get a different random number though, so the component itself is working, it's just the asynchronous part that is not.

My javascript console is fairly useless, there are no errors or warnings, just some logging from Stimulus itself which seems to suggest that at least Stimulus itself is working as intended:

application #starting <stimulus.js:1683>
application #start <stimulus.js:1683>

Is anyone here familiar enough with this new tech to point me into the right direction?

CodePudding user response:

Had this exact issue today. From your logs it seems that the Stimulus controller is not being loaded.

Make sure your controller.json file contains the controller:

{
    "controllers": {
        "@symfony/ux-live-component": {
            "typed": {
                "enabled": true,
                "fetch": "eager",
                "autoimport": {
                    "@symfony/ux-live-component/styles/live.css": true
                }
            }
        }
    },
    "entrypoints": []
}

Also your bootstrap.js should contain the following:

import { startStimulusApp } from '@symfony/stimulus-bridge';

// Registers Stimulus controllers from controllers.json and in the controllers/ directory
export const app = startStimulusApp(require.context(
  '@symfony/stimulus-bridge/lazy-controller-loader!./controllers',
  true,
  /\.(j|t)sx?$/
));
  • Related