Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

PttRulez's avatar
Level 21

Property changes without obvious reason for me

Hi. I've face strange behaviour. after clicking button which calls 'sync' method which has temporary sleep() function in it, i'm getting errors which is cause because my activities property has become an array of empty arrays as i can see after logging. (or collection of empty collections). I'm getting exception from days method about $a->date being null.

  1. why is days() method even called again after sync? looks like i don't understand how rerendering works
  2. why would the property become collection of empty collections for no reason? I mean there definitely is some reason but which one ...
    local.DEBUG: $this->activities[[],[],[],[],[],[],[]]
0 likes
7 replies
PttRulez's avatar
Level 21

@tykus I used it as computed. then changed to just a function. How does livewire decide when to recompute property? In react we have array of dependencies in useMemo, for example. view:

<div class='grid grid-cols-7 gap-4'>
    @foreach($this->days() as $day)
      <livewire:activities.daycard :date="$day->get('date')" :activities="$day->get('activities')"/>
    @endforeach
  </div>
tykus's avatar

This isn’t React, it is server-rendered PHP, if your template calls $this->days(), then that code is executed whenever the Component updates. With computed properties, you can cache the result (as described in the docs)

PttRulez's avatar
Level 21

@tykus I still can't solve why after calling sycnStrava i have only 1 card displayed. I haver refactored a bit

so you can see dd($this->days) in syncStrava function - it shows all days i need. but on the screen i get only the last one :(

so on the first render i get 31 days displayed:

 @foreach($this->days as $day)
      <livewire:activities.daycard :date="$day->get('date')" :activities="$day->get('activities')"/>
    @endforeach

but after clicking the button and executing syncStrava function i have only one last :( even though dd shows all of them

PttRulez's avatar
Level 21

@tykus looks like i have found the issue. I had to put wire:key property on each card But now I've got another problem. After clicking syncStrava, my cards are not updated. I can see in livewire inspector that days property has changed. It's 13th element has changed but still it's not displayed on the screen. Looks like the component is not refreshed

PttRulez's avatar
Level 21

And here i found the solution! :D In <livewire:activities.daycard /> I had to make property Reactive:

#[Reactive]
public ?Collection $activities;
LaryAI's avatar
Level 58

The issue you're experiencing seems to be related to how Livewire handles component reactivity and state management. Let's address your questions and provide a solution:

  1. Why is days() method even called again after sync?

    In Livewire, any change to a public property can trigger a re-render of the component. When you call the sync method, even though it only contains a sleep(2), it might be causing a re-render due to some implicit state change or because Livewire is set to re-evaluate the component's state after an action.

  2. Why would the property become a collection of empty collections?

    This could be happening if the activities property is being reset or not properly maintained between renders. If getActivities is not being called again, the activities property might be losing its data due to some unintended side effect.

Solution

To address these issues, consider the following steps:

  • Ensure activities is properly initialized and maintained: Make sure that the activities property is correctly populated and not inadvertently reset. You might want to log the output of getActivities to ensure it's returning the expected data.

  • Check for unintended state changes: Ensure that no other part of your component or any lifecycle hooks are modifying activities unexpectedly.

  • Debug the reactivity: Add logging to see when and why days() is being called. This can help you understand the reactivity flow.

Here's a revised version of your component with added logging and checks:

Additional Tips

  • Check the Strava service: Ensure that the getActivities method in your Strava service is functioning correctly and returning the expected data.

  • Livewire Lifecycle Hooks: Consider using lifecycle hooks like updated or render to debug when and why your component is re-rendering.

By following these steps, you should be able to identify the root cause of the issue and ensure that your component behaves as expected.

Please or to participate in this conversation.