Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Effects not firing in response to reactive list #22

Closed
meatballs opened this issue Oct 24, 2024 · 6 comments
Closed

Effects not firing in response to reactive list #22

meatballs opened this issue Oct 24, 2024 · 6 comments

Comments

@meatballs
Copy link
Member

When using a reactive_list, I'm finding that using a simple assignment in an effect does not cause it to fire when the list changes (except for the first change). Instead, I have to do some operation on it.

e.g.

from anvil_reactive.main import reactive_list, effect


class ReactiveClass:
    signal = reactive_list()

    @effect
    def react_to_signal(self):
        _ = self.signal
        print("react_to_signal fired")

    @effect
    def react_to_signal_with_len(self):
        _ = len(self.signal)
        print("react_to_signal_with_len fired")


reactive_test = ReactiveClass()

reactive_test.signal.append(1)
reactive_test.signal.append(2)

gives

react_to_signal fired
react_to_signal_with_len fired
react_to_signal_with_len fired

Clone link for this example code: https://anvil.works/build#clone:3QI3BEYGOXNH2RGK=PINMJMBUL5U4O5NWS6CSAKDA

@meatballs
Copy link
Member Author

Is this perhaps related to #5 and it's the print causing the problem?

In my real example, I have some logging occurring, which would have much the same effect.

@s-cork
Copy link
Contributor

s-cork commented Oct 24, 2024

What's the actual function? Typically if you want to react to the whole list you have to operate on the list.

@meatballs
Copy link
Member Author

meatballs commented Oct 24, 2024

Fair enough! Here's the actual function:

    @render_effect
    def refresh_tabulator(self):
        # I'm not sure why I need to use len here but it doesn't work
        # with just a simple assignment. There has to be some sort of
        # op on the signal in order for the function to fire.
        _signal = len(self.store.changelog)  # noqa unused_variable
        self.logger.debug("ReactivePersistenceTabulator: Refreshing tabulator")
        if not self.store or not self.store.view:
            self.logger.debug("ReactivePersistenceTabulator: Store is empty. Bailing out.")
            return
        if self.tabulator is None:
            self.logger.debug("ReactivePersistenceTabulator: No tabulator exists yet. Building it...")
            self.build_tabulator()
            return
        self.tabulator.deselect_row()
        self.tabulator.clear_app_table_cache()
        self.tabulator.set_data()

self.store is an instance of a class that has reactive attributes.

store.view is a data tables view - so it doesn't actually change. I just need a signal to tabulator to refresh and run the search on the view.

I suppose I could just use a counter that I increment any time a relevant event occurs.

@s-cork
Copy link
Contributor

s-cork commented Oct 24, 2024

yeah - so just appending doesn't change the list
but reading the len of the list does cause the effect to re-run because the length changes anytime you append

An incrementing counter will do the same job
I think this is probably the correct behaviour
Are any of those other tabulator methods actually reading from the changelog?

@meatballs
Copy link
Member Author

meatballs commented Oct 24, 2024

gotcha! No, nothing else is reading from there. It's purely a signal.

@s-cork
Copy link
Contributor

s-cork commented Oct 25, 2024

closing this issue for now

@s-cork s-cork closed this as completed Oct 25, 2024
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants