-
-
Notifications
You must be signed in to change notification settings - Fork 44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Bug]: App is "frozen" when reactive()
data is not passed
#1307
Comments
It's not that bad, you can see a huge button with We could disable the ability to go through modules, and grey them out, leaving only the |
@m7pr in the range of all the issue we solved "it is not bad", but inconsistent with |
Related to #1308 Acceptance Criteria
|
Alternative solution to #1330. Closes #1304, #1307, and #1308 1. When teal_data_module fails, then teal-module-tabs are disabled. When teal_data_module returns teal_data again teal-module-tabs are enabled 2. When reactive data passed directly to srv_teal fails, then the whole tab-panel is hidden and error message is shown. Warning messages are displayed over tab-panel. 3. when teal_transform_module fails then following teal_transform_module(s) show generic message that something was wrong. Reason for this is the same as (3). 4. when teal_transform_module fails then teal-module output is disabled and generic failure message is shown in the main panel. We decided to show a generic failure message as "real failure message" should be only shown in the place where error occurred to no cause confusion. 5. failing teal_data_module/teal_transform_module fallbacks to previous valid data (see exaplanation below) The most important part of the implementation is that when teal_data_module fails then it return the previous valid data (i.e. it return unchanged data). This means that failure doesn't trigger downstream reactivity and we don't need to deal with `data` input as error. In other words, this implementation halts reactivity when something goes wrong. When something goes wrong, teal-module-output is hidden and instead error message is displayed. Also, I've moved `data` completely away from `ui` and now if there is `teal_data_module` then data-tab is added dynamically. <details> <summary>app w/ teal_data_module</summary> ```r options( teal.log_level = "TRACE", teal.show_js_log = TRUE, # teal.bs_theme = bslib::bs_theme(version = 5), shiny.bookmarkStore = "server" ) # pkgload::load_all("teal.data") pkgload::load_all("teal") make_data <- function(datanames = c("ADSL", "ADTTE")) { data_obj <- teal.data::teal_data() if ("ADSL" %in% datanames) { data_obj <- within(data_obj, ADSL <- teal.data::rADSL) } if ("ADTTE" %in% datanames) { data_obj <- within(data_obj, ADTTE <- teal.data::rADTTE) } join_keys(data_obj) <- default_cdisc_join_keys[datanames] teal.data::datanames(data_obj) <- datanames data_obj } trans <- list( teal_transform_module( ui = function(id) { ns <- NS(id) tagList( selectizeInput( ns("errortype"), label = "Error Type", choices = c( "ok", "insufficient datasets", "no data", "qenv.error", "error in reactive", "validate error", "silent.shiny.error", "not a reactive" ) ) ) }, server = function(id, data) { moduleServer(id, function(input, output, session) { logger::log_trace("example_module_transform2 initializing.") reactive({ switch(input$errortype, ok = data(), `insufficient datasets` = teal:::.subset_teal_data(data(), "ADSL"), `no data` = teal_data(), qenv.error = within(teal_data(), stop("\nthis is qenv.error in teal_transform_module\n")), `error in reactive` = stop("\nerror in a reactive in teal_transform_module\n"), `validate error` = validate(need(FALSE, "\nvalidate error in teal_transform_module\n")), `silent.shiny.error` = req(FALSE) ) }) }) } ) ) data <- teal_data_module( once = FALSE, ui = function(id) { ns <- NS(id) tagList( selectizeInput( ns("errortype"), label = "Error Type", choices = c( "ok", "insufficient datasets", "no data", "qenv.error", "error in reactive", "validate error", "silent.shiny.error", "not a reactive" ) ), actionButton(ns("submit"), "Go!") ) }, server = function(id, ...) { moduleServer(id, function(input, output, session) { logger::log_trace("example_module_transform2 initializing.") eventReactive(input$submit, { switch(input$errortype, ok = make_data(), `insufficient datasets` = make_data(datanames = "ADSL"), `no data` = teal_data(), qenv.error = within(data(), stop("\nthis is qenv.error in teal_data_module\n")), `error in reactive` = stop("\nerror in a reactive in teal_data_module\n"), `validate error` = validate(need(FALSE, "\nvalidate error in teal_data_module\n")), `silent.shiny.error` = req(FALSE) ) }) }) } ) app <- teal::init( data = data, modules = list( example_module("mod-1", transformers = c(trans, trans, trans), datanames = c("ADSL", "ADTTE")), example_module("mod-2", transformers = trans, datanames = c("ADSL", "ADTTE")), module( label = "I was made to annoy you", ui = function(id) NULL, server = function(id, data) { moduleServer(id, function(input, output, session) { observe({ teal.data::datanames(data()) ADSL <- data()[["ADSL"]] ADSL$AGE }) observeEvent(data(), { print(data()[["ADSL"]]$SEX) }) }) }, datanames = "ADSL" ) ), filter = teal_slices( teal_slice("ADSL", "SEX"), teal_slice("ADSL", "AGE", selected = c(18L, 65L)), teal_slice("ADTTE", "PARAMCD", selected = "CRSD"), include_varnames = list( ADSL = c("SEX", "AGE") ) ) ) runApp(app) ``` </details> <details> <summary>app wrapped</summary> ```r options( teal.log_level = "TRACE", teal.show_js_log = TRUE, # teal.bs_theme = bslib::bs_theme(version = 5), shiny.bookmarkStore = "server" ) library(scda) pkgload::load_all("teal") make_data <- function(datanames = c("ADSL", "ADTTE")) { data_obj <- teal.data::teal_data() if ("ADSL" %in% datanames) { data_obj <- within(data_obj, ADSL <- teal.data::rADSL) } if ("ADTTE" %in% datanames) { data_obj <- within(data_obj, ADTTE <- teal.data::rADTTE) } join_keys(data_obj) <- default_cdisc_join_keys[datanames] teal.data::datanames(data_obj) <- datanames data_obj } ui_data <- function(id) { ns <- NS(id) tagList( selectizeInput( ns("errortype"), label = "Error Type", choices = c( "ok", "insufficient datasets", "no data", "qenv.error", "error in reactive", "validate error", "silent.shiny.error", "not a reactive" ) ), actionButton(ns("submit"), "Go!") ) } srv_data <- function(id, ...) { moduleServer(id, function(input, output, session) { logger::log_trace("example_module_transform2 initializing.") eventReactive(input$submit, { switch(input$errortype, ok = make_data(), `insufficient datasets` = make_data(datanames = "ADSL"), `no data` = teal_data(), qenv.error = within(data(), stop("\nthis is qenv.error in teal_data_module\n")), `error in reactive` = stop("\nerror in a reactive in teal_data_module\n"), `validate error` = validate(need(FALSE, "\nvalidate error in teal_data_module\n")), `silent.shiny.error` = req(FALSE) ) }) }) } modules <- modules( teal.modules.general::tm_data_table("Data Table"), example_module("Example Module", datanames = "ADTTE"), module( ui = function(id) { ns <- NS(id) tagList( tableOutput(ns("filter_summary")) ) }, server = function(id, datasets) { moduleServer(id, function(input, output, session) { output$filter_summary <- renderTable({ datasets$get_filter_overview(datanames = datasets$datanames()) }) }) } ) ) shinyApp( ui = function(request) { fluidPage( ui_data("data"), ui_teal(id = "teal", modules = modules) ) }, server = function(input, output, session) { data_rv <- srv_data("data", data = data, modules = modules) srv_teal(id = "teal", data = data_rv, modules = modules) } ) ``` </details> --------- Signed-off-by: Vedha Viyash <[email protected]> Signed-off-by: Marcin <[email protected]> Co-authored-by: vedhav <[email protected]> Co-authored-by: Vedha Viyash <[email protected]> Co-authored-by: m7pr <[email protected]> Co-authored-by: Marcin <[email protected]> Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: 27856297+dependabot-preview[bot]@users.noreply.github.com <27856297+dependabot-preview[bot]@users.noreply.github.com>
What happened?
When passing
data
as (unevaluated)eventReactive
tosrv_teal
directly then the teal-app looks like frozen. Propose a better solution for this.app code
The text was updated successfully, but these errors were encountered: