4

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 Answers3

2

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.

Alex P
  • 1,574
  • 13
  • 28
  • This kind of solves my problem. But in the real application I want to stop server.R from executing a part of it's code and don't show the already executed stuff if a certain value becomes false. It is like a log out function, that other computer users don't see what you have calculated. Is there maybe a way to restart a R session? – alfred j. quak Aug 04 '17 at 07:36
  • for the reset of the shiny app i found a good answer: https://stackoverflow.com/questions/25062422/restart-shiny-session – alfred j. quak Aug 04 '17 at 07:52
2

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)
Florian
  • 24,425
  • 4
  • 49
  • 80
0

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)
Pork Chop
  • 28,528
  • 5
  • 63
  • 77