livebook-dev / kino

Client-driven interactive widgets for Livebook
Apache License 2.0
372 stars 65 forks source link

`Kino.Input.read` does not get the current value when used inside `Kino.VegaLite.periodically` #167

Closed PhillippOhlandt closed 2 years ago

PhillippOhlandt commented 2 years ago

I wanted to use a checkbox to control what is happening inside a Kino.VegaLite.periodically but Kino.Input.read always returns the value that was set when the iteration started.

These are the Livebook code cells:

frame = Kino.Frame.new()
checkbox = Kino.Input.checkbox("My Checkbox")
Kino.VegaLite.periodically(frame, 1000, 1, fn i ->
  IO.inspect Kino.Input.read(checkbox )

  {:cont, i + 1}
end)

If run as is, the initial checkbox value will be false which will be printed to the output. Toggling the checkbox does not reflect in the new output.

josevalim commented 2 years ago

This is correct. The values are not propagated to the cells until the cells are reevaluated. I think you can change this by using Kino.Control.stream(...) passing the checkbox and the interval, and calling Kino.VegaLite push API to update the chart: https://hexdocs.pm/kino/Kino.Control.html#stream/1

PhillippOhlandt commented 2 years ago

Ah that worked, thanks.

Here the updated code:

frame = Kino.Frame.new()
checkbox = Kino.Input.checkbox("My Checkbox")
interval = Kino.Control.interval(1000)

value = Kino.Input.read(checkbox)
Kino.Control.stream([checkbox , interval], value, fn event, v ->
  case event do
    %{type: :interval} ->
      if (v) do
        # do some action
      end
      v
    %{type: :change, value: value} -> value
  end
end)