Genie Discord forum
![Author Avatar](https://cdn.discordapp.com/embed/avatars/2.png)
Hi!
I am quite new to Julia and this is my first time using Genie. So far I quite like it, but I am struggling with something at the moment. I want to use structs in my app, but I am encountering some unexpected behavior in the reactivity/communication of objects between the back-end and the UI. I included a simple example to illustrate my problem.
I created a testDict
and a testStruct
containing an x
and y
variable. The UI has a button that increments both x
s in the UI and a button that increments both y
s in the back-end. Some observations:
- The
@onchange
for incrementingx
is triggered on thetestDict
, but not on thetestStruct
- Incrementing y is not communicated to the UI for either
testDict
ortestStruct
I didn't find any up-to-date examples on this using the ReactiveTools API, so decided to post here. Any ideas on how to get this to work? Is this even supported?
using GenieFramework
@genietools
mutable struct demo
x::Number
y::Number
end
@app begin
@in testDict = Dict("x" => 1, "y" => 2)
@in testStruct = demo(1, 2)
@event :printtest begin
@show testDict
@show testStruct
end
@event :incrementy begin
testDict["y"] += 1
testStruct.y += 1
end
@onchange testDict begin
@show testDict
end
@onchange testStruct begin
@show testStruct
end
end
function ui()
[
row([p("Dict:{{testDict}}")]),
row([p("Struct:{{testStruct}}")]),
row([
btn("Increment X", @on("click", "testDict.x++; testStruct.x++")),
btn("Increment Y", @on("click", :incrementy)),
btn("Show in console", @on("click", :printtest)),
])
]
end
@page("/", ui)
up()
![Author Avatar](https://cdn.discordapp.com/avatars/743412727464067154/bc30abeb49653e9978c0f7c90f4486a8.png?size=512)
When you declare a reactive variable, the entire variable is reactive. This means that handlers will only be triggered when its value is changed, not when one of its field changes. For instance, if you define a button that modifies the first entry in an array like this:
@app begin
@in array = [1,2,3,4]
@in show_array = false
@onchange array begin
@show array
end
@onbutton show_array begin
@show array
end
end
ui = [btn("Increase count", @click("array[0] += 1")), btn("Show in REPL", @click(:show_array)), "{{array}}"]
@page("/", ui)
You'll see that when clicking "Increase count" the array in the page does not change, and that the handler is not triggered and therefore no message is shown in the repl. If you click the "show in repl" button, the REPL will show 1,2,3,4, which indicates that no modification took value.
If you want to trigger the handler, you need to change the entire array as
ui() = [btn("Click me", @click("array = [4,5,6,7]")), btn("Show in REPL", @click(:show_array)), "{{array}}"]
![Author Avatar](https://cdn.discordapp.com/avatars/743412727464067154/bc30abeb49653e9978c0f7c90f4486a8.png?size=512)
Also, another thing. The testDict
handler was triggered in your example because you are firing the :incrementy
event. I'm not sure it'd work if you were to just modify the Dict inside the button @on
event handler.
Hope this helped!
![Author Avatar](https://cdn.discordapp.com/embed/avatars/2.png)
Thanks for your response!
Ah ok, I see... The array elements indeed behave the same way as the struct fields.
Interesting that a Dict does seem to have reactive fields, because the "increment x" button does trigger the testDict
handler for me (see screenshot). Also the representations in Vue devtools of testDict
and testStruct
look identical, so it does seem to me there is a difference in how Dicts and structs are handled. Which makes sense from an implementation point of view, but at least from the Vue side it seems to be possible to have reactive object fields/elements.
But does this mean in general that "recursive" reactivity, i.e. react to fields/elements of reactive objects changing, is not supported? If so, are there any plans to support that in the future? To me that would make the framework much more powerful, allowing for more complicated interactions.
![](https://cdn.discordapp.com/attachments/1163746095155916800/1163852877291323392/image.png?ex=65411575&is=652ea075&hm=f160340c6b0b9618ca8593b366f6e1711c4ae359bdcc3f8bf66f320ee176759c&)