I have a much larger app that runs
on reactiveValues() and other such not-so-great coding choices, and I
have made the decision (inspired by Joe's talk in 2016) to rehaul it and work mostly with reactive
functions and modules.
I have hit a bump though. I was wondering what the proper method is for activating a module using an actionButton. I'd like the user to press an actionButton to confirm a text input, and this retrieves the reactive output of a module. Most (all?) of the module examples are very simple and just plot stuff -- I want my modules to be activated with buttons, and that requires some tricky usage of observeEvent() -- unless I am out of my element here.
I boiled down my example below. The first ("modular") works, but the table updates whenever the text is changed. When I remove modularity ("unModularized"), everything works fine -- the table only updates when the button is pressed. I must be missing something fundamental.
If this is the wrong (or inadvisable) way to approach modules, please tell me what to do to make it better. Thanks for your help.
modular
formatName <- function(n) paste(strsplit(n, split=' ')[[1]], collapse='_')
# UI part of the module
queryDB_UI <- function(id) {
ns <- NS(id)
tagList(
textInput(ns("name"), label = "Input name")
)
}
queryDB <- function(input, output, session, spName) {
query <- reactive({
q <- spocc::occ(input$name)
# extract occurrence tibble
tbl <- q[['gbif']]$data[[formatName(input$name)]]
return(tbl)
})
return(query)
}
# UI
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
queryDB_UI('id1'),
actionButton("go", "Search")
),
mainPanel(
DT::dataTableOutput('tbl')
)
)
)
# Server side
server <- function(input, output, session){
observeEvent(input$go, {
x <- callModule(queryDB, 'id1', spName)
output$tbl <- DT::renderDataTable(x())
})
}
shinyApp(ui, server)
unModularized
formatName <- function(n) paste(strsplit(n, split=' ')[[1]], collapse='_')
# UI part of the module
queryDB_UI <- function(id) {
ns <- NS(id)
tagList(
textInput(ns("name"), label = "Input name")
)
}
queryDB <- function(input, output, session) {
query <- reactive({
q <- spocc::occ(input$name)
# extract occurrence tibble
tbl <- q[['gbif']]$data[[formatName(input$name)]]
return(tbl)
})
return(query)
}
# UI
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
# queryDB_UI('id1'),
textInput("name", label = "Input name"),
actionButton("go", "Search")
),
mainPanel(
DT::dataTableOutput('tbl')
)
)
)
# Server side
server <- function(input, output, session){
# x <- callModule(queryDB, 'id1')
observeEvent(input$go, {
q <- spocc::occ(input$name)
# extract occurrence tibble
tbl <- q[['gbif']]$data[[formatName(input$name)]]
# output$tbl <- DT::renderDataTable(x())
output$tbl <- DT::renderDataTable(tbl)
})
}
shinyApp(ui, server)