user2602640
user2602640

Reputation: 740

Shiny eventReactive requiring two invalidations

There are many examples of Shiny apps with eventReactive with multiple inputs that responds when either of the inputs are invalidated. However, I'm trying to create an app with an eventReactive that runs when the app is only started, and only when both the Val1 textInput is updated and the actionButton is pressed. Below is a stripped-down version of my app.

I've tried the curly brackets, the c() approach, and !is.null(input$Val) & !is.null(input$Run) in the event portion, but all without success (for the latter - because I assume that an inputText is returning a non-NULL value is all cases, but I can't figure out what it returns when invalidated...).

Many thanks!

library(shiny)
library(shinydashboard)

server <- function(input, output, session){
    dat <- eventReactive(input$Val1, { 
            data.frame(x = input$Val1, y = 1)
            }, ignoreNULL=FALSE) 

    output$table <- renderTable({ 
        dat()
        })} 

sidebar <- dashboardSidebar(
                textInput(inputId = "Val1", label = "Val1", value = "5"),
                textInput(inputId = "Val2", label = "Val2", value = "51"),
                actionButton("Run", "Run", class = "btn-success")) 

ui <- dashboardPage(header = dashboardHeader(), 
    sidebar = sidebar,
    body = dashboardBody(mainPanel(fluidRow(tableOutput("table")))))

shinyApp(ui, server) 

Upvotes: 0

Views: 135

Answers (1)

starja
starja

Reputation: 10365

Here is a solution that compares the current value of Val1 with the value of Val1 at the last trigger of eventReactive. I don't do the comparison (and use req for it) directly in the eventReactive because then in the case it was triggered but Val1 didn't change, dat wouldn't show anything (and also lose the last shown value).

library(shiny)
library(shinydashboard)

server <- function(input, output, session){
  comparison_values <- reactiveValues(trigger_event = 0,
                                      previous_input = "value_on_startup")
  
  observeEvent(input$Run, {
    if (input$Val1 != comparison_values$previous_input) {
      comparison_values$trigger_event <- comparison_values$trigger_event + 1
      comparison_values$previous_input <- input$Val1
    }
  })
  
  dat <- eventReactive(comparison_values$trigger_event, {
    data.frame(x = input$Val1, y = 1)
  }, ignoreNULL=FALSE) 
  
  output$table <- renderTable({ 
    dat()
  })} 

sidebar <- dashboardSidebar(
  textInput(inputId = "Val1", label = "Val1", value = "5"),
  textInput(inputId = "Val2", label = "Val2", value = "51"),
  actionButton("Run", "Run", class = "btn-success")) 

ui <- dashboardPage(header = dashboardHeader(), 
                    sidebar = sidebar,
                    body = dashboardBody(mainPanel(fluidRow(tableOutput("table")))))

shinyApp(ui, server) 

Upvotes: 1

Related Questions