1

I'm new to R development and I am struggling a little bit how I can achieve that. I have a piece of code where I observe two action buttons waiting for clicks on them. Now I want know in the if statement which one of them was clicked, but my implementation is not working. I already searched some possible solution but I was not able to find it. Someone can give me a little help with that? Thanks!

observeEvent({c(input[["button1"]], input[["button2"]])}, {        

      output$mean<- renderPlotly({            

       if(input[["button1"]]){ 

           output_mean(out(), start_date(), geo(), language(), grupo(), TRUE, "button1")

        }else if(input[["button2"]]){

           output_mean(out(), start_date(), geo(), language(), grupo(), TRUE, "button2")

        }
      })

    #}
  })
r2evans
  • 141,215
  • 6
  • 77
  • 149
Erick
  • 147
  • 2
  • 12
  • Why do you nest a `render*` within an `observe*`? Seems rather redundant and complicating. (This doesn't solve your problem, but it may prevent others later.) – r2evans Apr 15 '18 at 02:26
  • 1
    @r2evans I am sorry but I did not know about that. I am new in here so I just did know about that. But I already accepted the answers for my previous questions. Thanks! – Erick Apr 15 '18 at 18:23

1 Answers1

2

Two things:

  • render* functions are inherently reactive, so they should not be nested within another. In this case, it is already able to react without adding anything.

  • Action buttons work by incrementing their value each time it is pressed. This means if a user clicks it faster than R can react, it might actually be incremented by 2 (unlikely but perhaps feasible). The act of the button's value changing (incrementing) is what triggers the reaction, so you need to know what the previous values were to know which one (assuming only one) was clicked.

Try the following:

server <- function(input, output, session) {
  buttonstates <- reactiveValues(one=0, two=0)
  output$mean <- renderPlotly({
    req(input$button1, input$button2)
    if (input$button1 != buttonstates$one) {
      buttonstates$one <- input$button1
      output_mean(out(), start_date(), geo(), language(), grupo(), TRUE, "button1")
    } else if (input$button2 != buttonstates$two) {
      buttonstates$two <- input$button2
      output_mean(out(), start_date(), geo(), language(), grupo(), TRUE, "button2")
    }
  })
}

Another option would be to separate the button-determination into its own reactive block. The advantage of this is that it simplifies your renderPlotly block:

server <- function(input, output, session) {
  buttonstates <- reactiveValues(one=0) # don't need two=0
  whichbutton <- reactive({
    req(input$button1, input$button2)
    if (input$button1 != buttonstates$one) "button1" else "button2"
  })
  output$mean <- renderPlotly({
    req(whichbutton())
    output_mean(out(), start_date(), geo(), language(), grupo(), TRUE, whichbutton())
  })
}

(If you aren't familiar with shiny::req, it prevents the block from firing if the required variable is not "truthy", as defined by shiny::isTruthy. It's a handy way to prevent premature-firing during shiny start and/or other issues.)

r2evans
  • 141,215
  • 6
  • 77
  • 149
  • 1
    Thanks a lot, @r2evans. Following your explanation I solved my problem. Thanks a lot. – Erick Apr 22 '18 at 13:11