Reputation: 6147
I am using assign
in for loop
to create new variables that I want to use in more than one outputs in shiny ui. Following is a sample code:
library(shiny)
ui <- fluidPage(
mainPanel(fluidRow(textOutput("a")),
fluidRow(textOutput("b")))
)
server <- function(input, output) {
m <- reactive({1:5})
output$a <- renderPrint({
for (i in 1:length(m())){
assign(paste0("h",i), "u")
}
list(h1,h2)
})
output$b <- renderPrint({
list(h1,h2)
})
}
shinyApp(ui = ui, server = server)
Each output
in server
has its own environment. So, the variables h1
to h5
are created within output a
and therefore not accessible by output b
. See the result of running app:
[[1]] [1] "u" [[2]] [1] "u"
[[1]] function (...) tags$h1(...) <environment: namespace:htmltools> [[2]] function (...) tags$h2(...) <environment: namespace:htmltools>
Ideally, the second line should be same as the first line. If I move the for loop
to server
, there is a problem of reactivity:
Error in .getReactiveEnvironment()$currentContext() :
Operation not allowed without an active reactive context. (You tried to do something that can only be done from inside a reactive expression or observer.)
How can I make the for loop
reactive so that all the outputs could access them?
I have also tried doing following outside output
s:
observe({for (i in 1:length(m())){
assign(paste0("om",i), "u")
}})
and
reactive({for (i in 1:length(m())){
assign(paste0("om",i), "u")
}})
Since h1
is already a function in shiny, I changed the object name to "om". But using either of the above yields no good results:
output$a <- renderPrint({
list(length(m()), om1)
})
output$b <- renderPrint({
om1()
})
Error: object 'om1' not found
Error: could not find function "om1"
Upvotes: 3
Views: 2006
Reputation: 107567
As I tried to relay in the comment, move the for loop
outside the first renderPrint()
function, so the h1-h5 is available for both output$a
and output$b
.
From your code there is no reason the loop needs to be restricted to only output$a
as its parameter m
is defined outside anyway:
library(shiny)
ui <- fluidPage(
mainPanel(fluidRow(textOutput("a")),
fluidRow(textOutput("b")))
)
server <- function(input, output) {
m <- reactive({1:5})
for (i in 1:length(m)){
assign(paste0("h",i), "u")
}
output$a <- renderPrint({
list(h1,h2)
})
output$b <- renderPrint({
list(h1,h2)
})
}
shinyApp(ui = ui, server = server)
Upvotes: 2