Closed 0x009922 closed 2 months ago
This is expected, Kino.Input.read
should be used to read the input value in the executing cell, not in a background process. We make sure that Kino.Input.read
returns the value from the time the cell started executing. In a background process the return value is basically undefined; for example if you change the input and evaluate another cell, then the background process would get the latest value on next read. The reason we do this is because we track dependency between inputs and cells, so when a cell calls Kino.Input.read
, and the input value changes later, we mark that cell as stale.
For accessing the input value asynchronously you can either use Kino.Control.form
with input and submit button (so that all form inputs are sent together). Or, you can subscribe to both the input and the button, and keep track of the current value in the state as it changes:
text = Kino.Input.text("Type something")
button = Kino.Control.button("Click")
Kino.Control.tagged_stream(button: button, text: text)
|> Kino.listen(%{text: ""}, fn
{:text, event}, state ->
{:cont, %{state | text: event.value}}
{:button, _event}, state ->
IO.inspect(state.text, label: "current input value")
{:cont, state}
end)
Kino.Layout.grid([text, button])
We should add a note about this in the docs. @josevalim or perhaps we should change it such that Kino.Input.read
raises when called from any process other than the cell? There could be a false positive, for example if you try to read inside Task.async_stream
, but a simple workaround is to read the input into a variable upfront, which is guaranteed to be the same value anyway. wdyt?
@jonatanklosko raising an error works for me!
Example
Section