Ian
Ian

Reputation: 1165

Store a reactiveVal on session exit

In a server function with a reactiveVal, how can I write the value to local storage when the session disconnects?

For a non-reactive val, say x, I would do:

session$onSessionEnded(function() {
    save(x, file = filename)
    stopApp()
})

But if I'd earlier had x <- reactiveVal(x), then my guess at

session$onSessionEnded(function() {
    save(x(), file = filename)
    stopApp()
})

fails. Apparently, "[I] tried to do something that can only be done from inside a reactive expression or observer."

update with mwe

library(shiny)

server <- function(input, output,session) {

    msg1 <- 'Works fine.'
    msg2 <- reactiveVal('No worky.')

    session$onSessionEnded(function() {
        save(msg1, file = 'msg1.RData')
        msg <- msg2()
        save(msg, file = 'msg2.RData')
    })
}

shinyApp(ui = fluidPage(), server = server)

Upvotes: 1

Views: 246

Answers (1)

Florian
Florian

Reputation: 25435

Here is an example that works fine if there is only one user in an active process. We write the reactiveVal to the global environment any time it changes using the <<- operator. When the session ends, we write that global variable to a file.

This is also why it goes wrong if multiple users are in the same Shiny process simultaneously; they share the global environment. So if the sequence is: User 1 modifies, user 2 modifies, user 1 exits, user 2 exits, with this implementation we write the reactiveVal from user 2 to disk twice.

Hope this helps!

library(shiny)

server <- function(input, output,session) {

  msg1 <- 'Works fine.'
  msg2 <- reactiveVal('No worky.')

  observeEvent(msg2(),
               {
                msg <<- msg2() # Write to global environment 
               })

  session$onSessionEnded(function() {
    # Write from global environment to file
    save(msg, file = 'msg.RData')
  })
}

shinyApp(ui = fluidPage(), server = server)

Upvotes: 2

Related Questions