3
votes

In the following example, the text is not shown in the start. If I click on the "show"-Button the text appears. If I then click on the "hide"-Button nothing else happens anymore. In fact the "textis$visible" variable has always the correct value, but i think the if-statement in the observeEvent funktion is only calculated after the very first button click.

Is there a way to force observeEvent to re-evaluate the if statement? Or are there other ways to stop shiny from executing code in the server part and restart it again (in the real case there would be a whole bunch of function calls inside the if statement, not just hide and show some text)

library(shiny)

ui <- fluidPage(

actionButton(inputId="show","show"),
actionButton(inputId="hide","hide"),

textOutput(outputId = "some_text")
)


server <- function(input, output) {

  textis<-reactiveValues(visible=FALSE)

observeEvent(input$show,
             textis$visible<-TRUE)

observeEvent(input$hide,
             textis$visible<-FALSE)

observeEvent(textis$visible  , if(textis$visible){
  output$some_text<-renderText({"this is some text"})  
})}

shinyApp(ui = ui, server = server)
3

3 Answers

2
votes

The observeEvent expressions are evaluated any time the value of their event expression changes. But, in the code you have above, when textis$visible changes, the observer only has instructions to perform if textis$visible is true. In the code snippet below, I've used else{...} to give that observer an action to perform when testis$visible is not true.

  observeEvent(textis$visible  , if(textis$visible){
    output$some_text<-renderText({"this is some text"})  
  } else {output$some_text<-renderText({''}) }
  )}

So, if you paste the else clause above into your app, the output some_text will disappear when the hide button is clicked.

2
votes

It is not very good practice to put a render element in an observer (and it is unnecessary). Also since you have only one reactiveValue, you could use reactiveVal(), see the example below. You can call its value with text_visible(), and update it with text_visible(new_value).

Working example:

library(shiny)

ui <- fluidPage(

  actionButton(inputId="show","show"),
  actionButton(inputId="hide","hide"), 
  textOutput(outputId = "some_text")
)


server <- function(input, output) {

  text_visible<-reactiveVal(TRUE)

  observeEvent(input$show,
               text_visible(TRUE))

  observeEvent(input$hide,
               text_visible(FALSE))

  output$some_text<-renderText({ 
    if(text_visible()) 
      return("this is some text")
    else
      return("")
  })
}

  shinyApp(ui = ui, server = server)
0
votes

try something like this:

library(shiny)

ui <- fluidPage(

  actionButton(inputId="show","show"),
  actionButton(inputId="hide","hide"),
  textOutput(outputId = "some_text")
)

server <- function(input, output) {

  textis <- reactiveVal(F)
  observeEvent(input$show,{textis(T)})

  observeEvent(input$hide,{textis(F)})

  result <- eventReactive(textis(),{
    if(!textis()){
      return()
    }
    "this is some text"
  })

  output$some_text<-renderText({result()}) 
}

shinyApp(ui = ui, server = server)