(Edited: there's really only one bug and the original post was misleading)
It's impossible to do the following (which I think is how everyone would go about using modules + conditional panels):
conditionalPanel(
condition = paste0("input.", ns("smooth"), " == true"),
...
)
since the namespacing that ns
provides for modules includes a dash (i.e. moduleID-elementID
), JS gets mad, and we need to at least do a good job of documenting that, since there's no expectation that users should know the internals of how namespacing works (but in this case, this obviously becomes relevant). When the condition
of a conditionalPanel involves an input or output coming from a module, you need to do this (use brackets instead of a dot):
conditionalPanel(
condition = paste0("input['", ns("smooth"), "'] == true"),
...
)
Which is not really ideal... But unless we want to change the internals of NS
(which I don't think we do), we need to document this. I'd suggest doing it in the three places that people are probably going to check if they get in trouble:
cc @yonicd
Here's a small example:
library(shiny)
condpanelUI <- function(id) {
ns <- NS(id)
tagList(
checkboxInput(ns("checkbox"), "Make panel visible"),
conditionalPanel(paste0("input.", ns("checkbox")), "This is the conditional panel")
)
}
ui <- fluidPage(
condpanelUI("foo")
)
server <- function(input, output, session) {
}
shinyApp(ui, server)
The error message in Chrome's JS console is:
VM160:2 Uncaught ReferenceError: checkbox is not defined
at Object.eval (eval at scopeExprToFunc (utils.js:167), <anonymous>:2:32)
at utils.js:169
at ShinyApp.$updateConditionals (shinyapp.js:410)
at ShinyApp.dispatchMessage (shinyapp.js:507)
at WebSocket.c.onmessage (shinyapp.js:112)
And the value of expr
right before the error is "input.foo-checkbox"
.
If the code is changed from:
paste0("input.", ns("checkbox"))
to:
paste0("input['", ns("checkbox"), "']")
it works.
that's what i have now (and it doesnt work for me) is there a new shiny version since this thread was opened?
> packageVersion('shiny')
[1] ‘1.0.3’
aesColourContNS=function(type,session) {
ns<-session$ns
id=gsub("-a", "", ns("a"))
iId=paste0('pop',toupper(type),'fixedPal')
fP=ns(paste0('pop',toupper(type),'fixedPal'))
#column(width=2,
shiny::div(
shiny::selectizeInput(inputId = fP,
label='Pallete',
choices = c('Manual','Blues', 'BuGn', 'BuPu', 'GnBu', 'Greens', 'Greys', 'Oranges', 'OrRd', 'PuBu', 'PuBuGn', 'PuRd', 'Purples', 'RdPu', 'Reds', 'YlGn', 'YlGnBu', 'YlOrBr', 'YlOrRd'),
selected = 'Blues'),
shiny::conditionalPanel(paste0("input['", id, "-", iId ,"'] == Manual"),
lapply(c('Low','High'),function(x,type){
if(x=='Low'){
pad='padding:0px 0px 0px 10px;'
init.col='red'
}
if(x=='High'){
pad='padding:0px 10px 0px 0px;'
init.col='blue'
}
shiny::column(width=6, style=pad,
do.call(colourpicker::colourInput,
args=list(inputId = ns(paste0('pop',toupper(type),x)),
label = x,
value = init.col,
returnName = F,
showColour = "background")
)
)
},type)
)
)
}
@yonicd You need to change it here: https://github.com/metrumresearchgroup/ggedit/blob/ffc1a35/R/ggeditUI.R#L20
It just occurred to me, we could fix this by making the conditionalPanel
itself namespace-aware. It's probably too late to do this by default? But:
conditionalPanel("input.viewVerbose", ns = ns, ...)
And conditionalPanel
would add an attribute to its HTML element that indicates what namespace to use to populate input
/output
.
Huh, that would actually work extremely well I think.
joe is also answering me here simultaneously. did a pull for his patch, still not responding to the change in syntax
https://github.com/metrumresearchgroup/ggedit/pull/18
On Fri, Jun 2, 2017 at 11:57 AM, Winston Chang notifications@github.com
wrote:
@yonicd https://github.com/yonicd You need to change it here:
https://github.com/metrumresearchgroup/ggedit/
blob/ffc1a35/R/ggeditUI.R#L20—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/rstudio/shiny/issues/1586#issuecomment-305830959, or mute
the thread
https://github.com/notifications/unsubscribe-auth/ABrJX5mL5-iVuMS8eRck8_OgYk6JvCy1ks5sADEBgaJpZM4MB2EN
.
--
Yoni
You do not learn to swim from books and lectures on the theory of buoyancy
(Box 1990)
Here's a minimal example, with a plot added:
library(shiny)
condpanelUI <- function(id) {
ns <- NS(id)
tagList(
checkboxInput(ns("checkbox"), "Make panel visible"),
conditionalPanel(
# paste0("input['", ns("checkbox"), "']"), # Fixed version
paste0("input.", ns("checkbox")),
"This text should show only when checkbox is checked."
)
)
}
ui <- fluidPage(
condpanelUI("foo"),
plotOutput("plot")
)
server <- function(input, output, session) {
output$plot <- renderPlot({
plot(1:5, 1:5)
})
}
shinyApp(ui, server)
When deployed to shinyapps.io, the conditionalPanel doesn't work, and the plot doesn't display. However, if the condition is fixed (by commenting out the condition and uncommenting the other version), the plot displays fine. In the screenshot, on the left is the broken version, on the right is the fixed version, both deployed to shinyapps.io:
Interestingly, if the broken version is deployed to RSC, the plot still shows. I believe this is due to some different error handling on RSC. On the left, I've deployed the broken version to shinyapps.io. On the right, I deployed the broken version to RSC. Note the differences in the stack trace.
These apps are deployed to:
@alandipert If your plate isn't too full--it'd be great if we could take a look at this together next week (either you and I, or you and Winston). The fix is straightforward, but I think it'd be a good chance to introduce you to the ins and outs of modules and especially why we made some of the design decisions we did--I'm sure you will have a lot of "Why didn't you just..." questions as we go through it.
@jcheng5 and I looked at the difference between shinyapps.io and RSC, and the different behavior is due to different transports on the two platforms. RSC uses websockets, whereas shinyapps.io uses an emulation layer via sockjs.
On RSC, the messages from the server are processed individually, and a JS exception will stop the processing of just that message.
On shinyapps.io, the messages from the server can be batched up and sent all at once, and a JS exception will stop the processing of all messages that were batched.
In my example, the JS error happens while processing one of the earlier messages, and the plot is included in a later message. When the messages are not batched (as on RSC), the JS error doesn't affect the plot. When the messages are batched (as on shinyapps.io) the error causes the plot not to render.
On RSC, it's possible to use the sockjs emulation by pressing ctrl-alt-shift-A and unchecking "websocket", then reloading the app. If you do that, then it will behave like shinyapps.io: the plot won't show. (On shinyapps.io, pressing the key combo will also bring up the websocket option, but even though it can be checked and unchecked, it actually has no effect -- it never uses websockets.)
@yonicd Are you seeing any errors in your JS console? If so, those errors are probably preventing the plots from displaying.
I mean that the JS errors will probably prevent the plots from displaying when you deploy your app on Shiny Server Pro or shinyapps.io.
got it to work after seeing the js error. i had to force the rhs of the logical to be a string on the R side.
which was a typo on my part.
https://github.com/metrumresearchgroup/ggedit/commit/feaf6b183100b3a17ad818141035c9ccc78e0491
thanks!
Closed by #1735.
Most helpful comment
It just occurred to me, we could fix this by making the
conditionalPanel
itself namespace-aware. It's probably too late to do this by default? But:conditionalPanel("input.viewVerbose", ns = ns, ...)
And
conditionalPanel
would add an attribute to its HTML element that indicates what namespace to use to populateinput
/output
.