Search code examples
rshinyreactive-programmingshinymodules

Passing reactive to module server function with `updateSelectizeInput`


The goal of this module is to take a reactive input e.g. a dataframe dataset, and updates the choices argument in selectize input with the rownames of this reactive input dataframe.

It works fine without modularization, but when I try to implement the module server function, I get this error:

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 consumer.

Here is my attempt at modularizing the app, that produces the error:

select_ui <- function(id, label = 'select input'){
  tagList(
    selectizeInput(inputId = 'select_input',
                   label = 'Select input',
                   choices = NULL,
                   options = list(placeholder = 'Select')
    ),
    verbatimTextOutput('print')
  )
}

select_server <- function(id, choices) {
  moduleServer(id, function(input, output, session) {
    req(choices())

    output$print <- renderPrint({
      choices()
    })

    observeEvent(choices(), {
      updateSelectizeInput(
        session, 'select_input',
        choices = choices(),
        server = T)
    })
  })
}

select_app <- function(...){
  ui <- fluidPage(
    select_ui('select_input')
  )
  server <- function(input, output, session){
    choices <- reactive({
      rownames(datasets::ability.cov$cov)
      })
    select_server('select_input', choices = choices())
  }
  shinyApp(ui, server, ...)
}

The unmodularized, working app, that functions as intended:

# not modularized version:
select_app2 <- function(...){
  ui <- fluidPage(
    selectizeInput(inputId = 'select_input',
                   label = 'Select input',
                   choices = NULL,
                   options = list(placeholder = 'Select')
    ),
    verbatimTextOutput('print')
  )
  server <- function(input, output, session){
    choices <- reactive({
      rownames(datasets::ability.cov$cov)
    })

    output$print <- renderPrint({
      cat('here are the choices: ', choices())
    })

    observe({
      updateSelectizeInput(
        session, 'select_input',
        choices = choices(),
        server = T)
    })
  }
  shinyApp(ui, server, ...)
}

I think it has something to do with passing the reactive choices to my module server function, and also with the update* function.

Any insight appreciated!


Solution

  • You have req(choices()) outside a reactive context, that is the error (or one of the errors).

    Because you do select_server('select_input', choices = choices()) instead of select_server('select_input', choices = choices). –Stephane Laurent