Skip to content
Advertisement

Laravel Livewire Javascript data is not refreshed after component is re-rendered

I need support because my javascript data is not updating when the livewire component gets re-rendered.

I use Fullcalendar in a livewire component

<div>
    {{ dump($events) }} {{-- ⬅️[1] --}}
    <x-card class="mt-4">
        <div id='calendar'></div>
    </x-card>
    
    @push('scripts')
        <script src='https://cdn.jsdelivr.net/npm/fullcalendar@5.11.0/main.min.js'></script>
        <script src='https://cdn.jsdelivr.net/npm/fullcalendar@5.11.0/locales/de.js'></script>
        
        <script>
            document.addEventListener('contentChanged', function() {
                console.log(@js($events)); // ⬅️[3]
                var Calendar = FullCalendar.Calendar;
                var calendarEl = document.getElementById('calendar');
                //                ⬇️[2]
                var data = @js($events);
                var calendar = new FullCalendar.Calendar(calendarEl, {
                    locale: "de",
    
                    events: JSON.parse(data).map((event) => ({
                        ...event,
                        backgroundColor: event.title < 3 ? '#B23220' : (event.title < 11 ? '#C3B031' : '#20B22C'),
                        borderColor: event.title < 3 ? '#B23220' : (event.title < 11 ? '#C3B031' : '#20B22C'),
                    })),
    
                    headerToolbar: {
                        left: 'prev,next today',
                        center: 'title',
                        right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek'
                    },
                    
                    loading: function(isLoading) {
                        if (!isLoading) {
                            this.getEvents().forEach(function(e){
                                if (e.source === null) {
                                    e.remove();
                                }
                            });
                        }
                    },
                });
                calendar.render();
                @this.on(`refreshCalendar`, () => {
                    calendar.refetchEvents()
                });
            });
        </script>
        <link href='https://cdn.jsdelivr.net/npm/fullcalendar@5.11.0/main.min.css' rel='stylesheet' />
    @endpush
</div>

In my class I have $this->dispatchBrowserEvent('contentChanged'); in the render method.

When I update $events I see the updated data in the dump [1] but events [2] is not updated.

The log [3] shows always the same events

Advertisement

Answer

Since you’ve pushed the script out of your component (which is a good idea), it will not be touched when Livewire is re-rendering and doing its DOM-diffing.

So instead, you can pass the event-data as a parameter which you can accept in the event-listener.

So, add the data with the event,

$this->dispatchBrowserEvent('contentChanged', $this->events);

And accept it in the listener, by passing e into the callback (which is the event-object), and access the data in e.detail.

document.addEventListener('contentChanged', function(e) {
    var Calendar = FullCalendar.Calendar;
    var calendarEl = document.getElementById('calendar');
    var data = e.detail;
    // ...
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement