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)
Problem
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.)
Question
How can I make the for loop
reactive so that all the outputs could access them?
EDIT
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"