简体   繁体   中英

shiny reactive values update order

I have a shiny app that has a function that takes couple of minutes to compute. I want the user to be aware that the function is running and to wait (and not press the button again for example)

I built a dependencies of objects, hoping that it will show a 'wait' message, but for some reason it's not working.

In my server file I have this-

function(input, output, session) {
  inProgressValue <- reactiveVal('')
  inProgressValue2 <- reactiveVal(0)
  myCalculatedValue <- reactive(NULL)

  inProgressEvent <- observeEvent(input$myButton,{
    inProgressValue('In progress please wait')
  })
  inProgressEvent2 <- observeEvent(inProgressValue(),{
    inProgressValue2(input$myButton)
  })
  longFunctionEvent <- observeEvent(inProgressEvent2(),{
    #make some calculations
    inProgressValue('')
  })
  output$waiting <- renderText({
    inProgressPlsValue()
  })
  output$mainData <- renderPlot({
    #do some stuff with myCalculatedValue()
  })
}

In the ui file I have-

fluidRow(h3(textOutput('waiting'))),
fluidRow(h3(plotOutput('waiting')))

I was hoping that when the myButton would be clicked and the value would change, the first observer will be triggered and inProgressValue() would change to 'In progress please wait' which would be printed in the application. Then the second observer will be triggered and the value of inProgressValue2() would be set to the myButton value, all the calculation will be executed, the value of inProgressValue() would be changed back to an empty string that would not be shown, (the second observer would be triggered again, but the value of the button is still the same, so this should not cause the calculations to happen again)

The waiting message is never displayed, and the computation of the long function happens before the message is shown in the app. I was trying to use eventReactive instead of observeEvent , but for some reason the values didn't change when I clicked the button.

I read this difference between observeEvent and eventReactive and some other questions about the 2 functions, but could not figure out why my eventReactive didn't work, and used observers with reactive values instead.

There are some basic flaws in this code.

First and foremost - observers are used only for their "byproducts" (namely the code that they run in the background), and not to return values that can be assigned in another variables.

A minimal app that will achieve what you're trying to do will look something like that:

library(shiny)

shinyApp(

  ui = fluidPage(actionButton(inputId = "btn", label = "run")),

  server = function(input, output, session) {

    observeEvent(input$btn, {
      withProgress(
        message = "Please wait",
        value = 0.35,
        expr = {
          # some time consuming operations, e.g:
          mean(rnorm(n = 50000000)) 
        }
      )
    })

  }
)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM