Search code examples
rshinyobserversshiny-reactivity

ReactiveValues trigger different observeEvents not working


Problem: I have the following app. Essentially, I want to press the button to load the data. After the first time I load the data via button press I want to get ask if I want to save my changes. If yes, confirmation that changes were successfully saved, else show some other data (other data not included).

Approach I tried to solve it with observeEvent expressions which are triggered via reactiveValues. However, as you will observe when running the script below, this does not work out as expected.

Question: Any idea on what is wrong?

library(shiny)
library(shinyWidgets)
library(rhandsontable)

shinyApp(
  ui = fluidPage(
    actionButton("show", "Show data", width = "100%"),
    rHandsontableOutput("data_table")
  ),
  server = function(input, output) {
    
    rv <- reactiveValues(
      # Triggers
      pressed_first_time = 0,
      confirm_module = TRUE,
      save_module = TRUE,
      table_change = TRUE
    )
    
    observeEvent(input$show, ignoreInit = TRUE, {
      if (rv$pressed_first_time == 0){
        rv$pressed_first_time <- isolate(rv$pressed_first_time  + 1)
        rv$table_change <- isolate(!rv$table_change)
        cat("pressed_first time")
      } else {
        rv$pressed_first_time <- isolate(rv$pressed_first_time  + 1)
        rv$confirm_module <- isolate(!rv$confirm_module)
      }
    })
    
    observeEvent(rv$confirm_module, ignoreInit = TRUE,{
      confirmSweetAlert(
        session = session,
        inputId = session$ns("show_confirmation"),
        title = "Be careful, your changes might be lost",
        text = "Do you want to save your changes?",
        type = "question",
        btn_labels = c("Cancel", "Save"),
        btn_colors = NULL,
        closeOnClickOutside = FALSE,
        showCloseButton = FALSE,
        html = FALSE
      )
      cat("confirmation module")
      rv$save_module <- isolate(!rv$save_module)
      
    })
    
    observeEvent(rv$save_module, ignoreInit = TRUE, {
      if (isTRUE(input$show_confirmation)) { 
        sendSweetAlert(
          session = session,
          title = "Saved",
          text = "Updated data has been successfully saved",
          type = "success"
        )
        rv$table_change <- isolate(!rv$table_change)
        cat("saving module")
      } else {
        return()
      }
    })
    
    data_to_modify <- eventReactive(rv$table_change, ignoreInit = TRUE, {
      mtcars
    })
    
    handson_df <- eventReactive(rv$table_change, ignoreInit = TRUE, {
      cat("create handsons")
      req(data_to_modify())
      rhandsontable(data_to_modify())
    })
    
    
    output$data_table <- renderRHandsontable({
      cat("plot module")
      req(handson_df())
      
      htmlwidgets::onRender(handson_df(),change_hook)
      
    })
  }
)

Solution

  • Actually, I found out the problem. The link from data_to_modify to handson_df was missing. In the below solution I put them together but in principle adding another reactiveValue triggering handson_df from data_to_modify will also work

    library(shiny)
    library(rhandsontable)
    
    shinyApp(
      ui = fluidPage(
        actionButton("show", "Show data", width = "100%"),
        rHandsontableOutput("data_table")
      ),
      server = function(input, output) {
        
        rv <- reactiveValues(
          # Triggers
          pressed_first_time = 0,
          confirm_module = TRUE,
          save_module = TRUE,
          table_change = TRUE
        )
        
        observeEvent(input$show, ignoreInit = TRUE, {
          if (rv$pressed_first_time == 0){
            rv$pressed_first_time <- 1
            rv$table_change <- isolate(!rv$table_change)
            cat("pressed_first time")
          } else {
            rv$pressed_first_time <- 1
            rv$confirm_module <- isolate(!rv$confirm_module)
          }
        })
        
        observeEvent(rv$confirm_module, ignoreInit = TRUE,{
          confirmSweetAlert(
            session = session,
            inputId = session$ns("show_confirmation"),
            title = "Be careful, your changes might be lost",
            text = "Do you want to save your changes?",
            type = "question",
            btn_labels = c("Cancel", "Save"),
            btn_colors = NULL,
            closeOnClickOutside = FALSE,
            showCloseButton = FALSE,
            html = FALSE
          )
          
        })
        
        observeEvent(input$show_confirmation, ignoreInit = TRUE, {
          if (isTRUE(input$show_confirmation)) { 
            sendSweetAlert(
              session = session,
              title = "Saved",
              text = "Updated data has been successfully saved",
              type = "success"
            )
            rv$table_change <- isolate(!rv$table_change)
            cat("saving module")
          } else {
            return()
          }
        })
        
        data_to_modify <- eventReactive(rv$table_change, ignoreInit = TRUE, {
    
          rhandsontable(mtcars)
        })
        
        # handson_df <- eventReactive(rv$table_change, ignoreInit = TRUE, {
        #   cat("create handsons")
        #   req(data_to_modify())
        #   rhandsontable(data_to_modify())
        # })
        
        
        output$data_table <- renderRHandsontable({
          cat("plot module")
          req(data_to_modify())
          data_to_modify()
          # htmlwidgets::onRender(handson_df(),change_hook)
          
        })
      }
    )