[GenieFramework] Persist some actions after refreshing on web browser

Hi, all!

I am making a web-based monitoring app using Genie and Stipple.jl.

If an action or a function is triggered by @onchange, it does not persist after refreshing on web browser.

Here’s an MWE.

module App
using GenieFramework
@genietools

# global variable for status save
gen_on = false

@app begin
    @in mybutton = gen_on
    @out ranval = 0.

    @onchange mybutton begin
        if mybutton
            global gen_on = true
            @info "Generation starts!"
            @async begin
                while gen_on
                    ranval = rand()
                    sleep(1)
                end
            end
        else
            global gen_on = false
            @info "Generation stops!"            
        end
    end    
end

function ui()
    [
        cell([
            btn("Generate random number!", @click("mybutton = !mybutton"))
        ])
        cell([
            bignumber("Random value!", :ranval)
        ])
    ]
end

@page("/", ui)
end

In this code, clicking the button will trigger a while loop generating a random number per sec.
Once I click refresh button on the browser, the value will be no longer changed even though the while loop is still running. I have to click the button twice to see the generation again. It makes sense @onchange macro only senses the change of the value, and definitely no change has been made on mybutton after refresh…

Then, how can I change the code so that the random number generation will be displayed after refresh? As you can see above, my trial to use a global variable was not successful :frowning:

Thanks for any comments!

This would be my solution for a global counter:

using Stipple, Stipple.ReactiveTools
using StippleUI


gen_on::Bool = false
const ranval = Observable(0.0)

function startcounter(model = nothing)
    if gen_on
        msg = "Generation is already running!"
        @info msg
        model !== nothing && notify(model, type = "warning", msg)
    else
        @async begin
            global ranval, gen_on
            gen_on = true
            msg = "Generation starts!"
            @info msg
            model !== nothing && notify(model, type = "positive", msg)
            while gen_on
                ranval[] = rand()
                sleep(1)
            end
        end
    end
end

function stopcounter(model = nothing)
    global gen_on
    if gen_on
        gen_on = false
        msg = "Generation stops!"
        @info msg
        model !== nothing && notify(model, type = "negative", msg)
    else
        msg = "Generation is not running!"
        @info msg
        model !== nothing && notify(model, "warning", msg)
    end
end

@app begin
    @in mybutton = false
    @out ranval = 0.0

    @onchange isready begin
        synchronize!(__model__.ranval, @__MODULE__().ranval, bidirectional=false)
    end

    @onchange mybutton begin
        gen_on ? stopcounter(__model__) : startcounter(__model__)
    end    
end

function ui()
    htmldiv(card(class = "q-ma-lg", style = "max-width: 300px", [
        cardsection(row(class = "justify-center", btn(col = "auto", "Generate random number!", @click("mybutton = !mybutton"))))
        cardsection(bignumber(class = "column items-center", "Random value!", :ranval))
    ]))
end

@page("/", ui, post = x->(global model = x; nothing))
1 Like

Thank you so much for sharing a nice code!

It will be a useful primer for my self study.