Genie Discord forum

Author AvatarMordegai
8/20/2023, 1:58:19 PM

I have an @onchange block that changes the value of two variables. A change in those variables triggers another @onchange block but I would like to postpone that trigger until both variables are changed. Is that possible?

Here's the code:

@onchange remove_dem_tier begin
        if !isempty(dem_amounts)
            @show dem_percentages
            pop!(dem_percentages)
            dem_percentages = copy(dem_percentages)

            @show dem_amounts
            pop!(dem_amounts)
            dem_amounts = copy(dem_amounts)
        end
    end

@onchange set_telo, guaranteed_income, demurrage_free, dem_amounts, dem_percentages begin
        @show sumsy_initial_wealth

        if set_telo
            dem_tiers::Vector{Tuple{Real, Real}} = Vector{Tuple{Real, Real}}()

            for index in eachindex(dem_amounts)
                push!(dem_tiers, (dem_amounts[index], dem_percentages[index]/100))
            end

            sumsy_initial_wealth = Integer(round(telo(guaranteed_income, demurrage_free, dem_tiers)))
        end
    end

As can be seen, if the second @onchange block is triggered after I pop from percentages, I get an index error. Both arrays should always be kept at the exact same length before doing anything with them.

Thanks in advance!

Author AvatarPere
8/21/2023, 2:18:48 PM

Genie relies on Observables.jl to implement reactivity. I see in the docs that there is support for callback priorization https://juliagizmos.github.io/Observables.jl/stable/#Priority

so I guess it could be done. However, the current version of Stipple.jl does not allow for this kind of behavior.

I can think of two ways to implement what you need:

  1. watch only the dem_amounts variable and remove dem_percentages from @onchange. When the reactive handler is triggered due to a change in dem_amounts, we know that dem_percentages has also changed as the code shows a few lines above.
  2. Add a private reactive variable with @private twovars = 0,

and watch that one with @onchange twovars,.... Then, in the first reactive handler simply modify this twovars variable at the end of the block to trigger the other handler

Author AvatarMordegai
8/21/2023, 2:24:13 PM

Now I have another, related question however. I thought by myself, what if I just put the data in one multi dimensional array? That works ... but only in one direction it seems. I can display the data with 'dem_tiers[index]0' for example. but when I make changes to it, it's not registered. Is there a way to bind components to elements in a multi dimensional array or am I wishing for unicorns here? ๐Ÿ˜‰

Author AvatarMordegai
8/22/2023, 9:08:21 AM

Things are a bit more complicated then I described above it seems. I have the following html code: ```

When I  change the value of a dem_tiers[index][0] field, everything works fine and the value is changed in the model. But when I change the value of a dem_tiers[index][1] field, the change is not propagated to the model. Even the rules are not triggered.
Author AvatarMordegai
8/22/2023, 9:27:27 AM

Figured out why the rules are not triggered. Typo in the rules ๐Ÿ™‚ . I now changed '=>' into '>=' and the rules now work AND I figured out why I had a problem updating the data in the model. I initialised the array as 'dem_tiers = [[0, 1]]' and then tried to store a Float in it. It didn't trigger a (visible) error but it clearly didn't work. I changed the initialisation code to 'dem_tiers = [[0, 1.0]]' and now everything works fine. Thus, problem solved! ๐Ÿ™‚