Side effects and manually changing the UI

Matte's computation model means that a server function can only affect one output – the output with the same id as the function name. But what if you want to change more than one? What if your function needs to have side-effects? This is likely to happen when you have functions that change some session variable. As warned in the previous guide, session variables are not reactive – if you have multiple outputs that depends on a session variable you have to manually update them when you change the value.

This is where update_output comes in. update_output can be called from inside any server-side functions to manually an output variable to a new value.

Setting the scene with an example

Let's make this problem concrete with a problem. Let's extend the app from the previous guide so that, along with displaying how many times the number has been clicked, we also combine that number with a number from a slider. The example broken_sideeffect mocks this problem up. Let's run this app and see the problem:

matte_example("broken_sideeffect", "broken_sideeffect")
includet("app.jl")
run_app(BrokenSideEffect)

Open the app, which looks like this:

Push the button. You'll see the first output updates, but the second one does not. If you move the slider it does, because that re-triggers the output. But the button doesn't, because Matte doesn't recognise that my_count updates session.count.

Fixing the problem with side effects

We can fix this by changing how my_count works so that we explicitly and manually update the value of my_calc from within my_count:[1]

function my_count(my_button, slider, session)
    if my_button
        session.count += 1
        update_output("my_calc", slider * session.count, session)
    end
    session.count
end

Don't forget to add using Matte to your server module, so that we can access the update_output function.

If you replace my_count in your app.jl file, and refresh your app, it should now work properly. Both numbers will update every time you click the button.

This example is obviously extremely contrived. But in the next guide we'll see a concrete useful example of when you will want to use update_output: displaying progress notifications for long-running computations.

my_button as an input to my_calc so that my_calc, is recomputed anytime the button is pushed. This won't always work.

  • 1Of course, for an example this simple, you could also solve the problem by having