JuliaPluto / PlutoUI.jl

https://featured.plutojl.org/basic/plutoui.jl
The Unlicense
299 stars 54 forks source link

Select without Pluto rendered creates an error #274

Closed schlichtanders closed 7 months ago

schlichtanders commented 8 months ago

when using PlutoUI, the select statement throws an error if interpolated beforehand via string interpolation. Interestingly the Slider works without problems. I really need string interpolation, hence it would be great if all PlutoUI works here too.

image

# cell
using PlutoUI
# cell
bond = @bind a Slider(1:10)
# cell
HTML(repr("text/html", bond))
# cell
a
# cell
bond2 = @bind b Select(["potato šŸ ", "carrot šŸ„•"]; default = "potato šŸ ")
# cell
HTML(repr("text/html", bond2))
# cell
b

Here the error output in full

message

šŸšØ AbstractPlutoDingetjes: Bond value transformation errored.

exception

ArgumentError: invalid index: nothing of type Nothing
Stacktrace:
  [1] to_index(i::Nothing)
    @ Base ./indices.jl:300
  [2] to_index(A::Vector{Pair}, i::Nothing)
    @ Base ./indices.jl:277
  [3] _to_indices1(A::Vector{Pair}, inds::Tuple{Base.OneTo{Int64}}, I1::Nothing)
    @ Base ./indices.jl:359
  [4] to_indices
    @ ./indices.jl:354 [inlined]
  [5] to_indices
    @ ./indices.jl:345 [inlined]
  [6] getindex(A::Vector{Pair}, I::Nothing)
    @ Base ./abstractarray.jl:1296
  [7] transform_value(select::PlutoUI.BuiltinsNotebook.Select, val_from_js::String)
    @ PlutoUI.BuiltinsNotebook ~/.julia/packages/PlutoUI/bgVQx/src/Builtins.jl:667
  [8] transform_bond_value(s::Symbol, value_from_js::String)
    @ Main.PlutoRunner ~/.julia/dev/Pluto/src/runner/PlutoRunner.jl:2164
  [9] top-level scope
    @ ~/.julia/dev/Pluto/src/evaluation/Run.jl:442
 [10] eval(m::Module, e::Any)
    @ Core ./boot.jl:370
 [11] top-level scope
    @ ~/.julia/dev/Pluto/src/evaluation/WorkspaceManager.jl:540
 [12] eval(m::Module, e::Any)
    @ Core ./boot.jl:370
 [13] invokelatest(::Any, ::Any, ::Vararg{Any}; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ Base ./essentials.jl:819
 [14] invokelatest(::Any, ::Any, ::Vararg{Any})
    @ Base ./essentials.jl:816
 [15] (::Distributed.var"#110#112"{Distributed.CallMsg{:call_fetch}})()
    @ Distributed /usr/local/julia/share/julia/stdlib/v1.9/Distributed/src/process_messages.jl:285
 [16] run_work_thunk(thunk::Distributed.var"#110#112"{Distributed.CallMsg{:call_fetch}}, print_error::Bool)
    @ Distributed /usr/local/julia/share/julia/stdlib/v1.9/Distributed/src/process_messages.jl:70
 [17] macro expansion
    @ /usr/local/julia/share/julia/stdlib/v1.9/Distributed/src/process_messages.jl:285 [inlined]
 [18] (::Distributed.var"#109#111"{Distributed.CallMsg{:call_fetch}, Distributed.MsgHeader, Sockets.TCPSocket})()
    @ Distributed ./task.jl:514

value_from_js

"potato šŸ "

Anyone knowing what is going on? I am also looking for a workaround

schlichtanders commented 8 months ago

I found a workaround: using the following PlutoRunner internals

HTML(Main.PlutoRunner.format_output(bond2)[1])

works

fonsp commented 8 months ago

Thanks for the report! In the meantime, try to use HypertextLiteral.jl instead of HTML. A big advantage is that @htl does not render-to-html-and-then-interpolate, but it stores the orignal object (a Bond{Select}) and it gets rendered by Pluto on demand.

If you really need to use a pre-rendered HTML string, then you might get away with the embed_display (already available in notebook scope) function.

Most fancy Pluto inputs won't work when prerendered to HTML, that's a big reason why HypertextLiteral.jl was developed.

The solution to this issue will probably be to detect this situation and throw an error šŸ™ƒ