bastien herve
bastien herve

Reputation: 45

How to refresh Rdata objects in shiny app

My aim is to refresh .Rdata objects when the user confirms a dataset reloading through a shinyalert pop up. A small example below. Before loading the app I've created and saved 2 objects (DatasetNumber1 and DatasetNumber2) containing a label and data to be displayed.

When the app is launched I load by default DatasetNumber1 objects thanks to the global.R file. So now test and data objects from DatasetNumber1 are accessible through server.R AND ui.R, which I need to (not in this example, but in my full app). I want the user to be able to select the other dataset via the dropdown to refresh the global R objects and in the end the plotting.

The print statement in the server.R, after I've selected the other dataset in the dropdown, clicked on the Load button and validate through the shinyalert, confirms that the dropdown input changed but the load statement does not refresh R objects.

I've tried to make the loading reactive straight in the global.R script but I ended with the same result. Maybe the rendering is faster than the loading and so does not take the updated data in account to render...

In any case I do not want to reload neither the app nor the session.

Thanks !

#inputCreation.R

test <- "IamDatasetNumber1"
data <- c(1, 3, 6, 4, 9)
save(test, data, file = "./Test/DatasetNumber1.Rdata")

test <- "IamDatasetNumber2"
data <- c(2, 7, 9, 12, 13)
save(test, data, file = "./Test/DatasetNumber2.Rdata")

#global.R

library(shiny)
library(shinyjs)
library(shinyalert)

load("DatasetNumber1.Rdata")

#ui.R

shinyUI(
  fluidPage(
    useShinyjs(),
    div(
        id = "main_page",
        fluidRow( # -------------------------------------------------------
                  column(
                    2, offset=0,
                    selectInput("dropdown_dataset", "Dataset :", choices=c("DatasetNumber1", "DatasetNumber2"), selected="DatasetNumber1")
                  ),
                  column(
                    1, offset=0,
                    useShinyalert(),
                    actionButton("button_dataset", "Load"),
                  )
        ),
        fluidRow( # -------------------------------------------------------
                  uiOutput("test_text")
        ),
        fluidRow( # -------------------------------------------------------
                  plotOutput("test_plot")
        )
    )
  )
)

#server.R

shinyServer(
  function(input, output, session) {
    
    observeEvent(input$button_dataset, {
      shinyalert(title = "Are you sure?",
                 text = "This action can take a while",
                 type = "warning",
                 closeOnEsc = TRUE,
                 closeOnClickOutside = TRUE,
                 showCancelButton = TRUE,
                 showConfirmButton = TRUE,
                 confirmButtonText = "OK",
                 confirmButtonCol = "#AEDEF4",
                 cancelButtonText = "Cancel",
                 inputId = "shinyalert",
                 callbackR = function(x){
                   if(x){
                     showModal(modalDialog("Loading...", footer=NULL))
                     print(paste(input[["dropdown_dataset"]],sep=""))
                     load(paste(input[["dropdown_dataset"]],".Rdata",sep=""))
                     removeModal()
                   }
                 }
      )
    })
    output$test_text <- renderText(test)
    output$test_plot <- renderPlot(plot(data))
  }
)

Upvotes: 1

Views: 1270

Answers (2)

bastien herve
bastien herve

Reputation: 45

With @Tyler's help !

#server.R

shinyServer(
  function(input, output, session) {
    
    react <- reactiveVal()
    react(local({load("DatasetNumber1.Rdata"); list(test=test,data=data)}))

    observeEvent(
      input$shinyalert,
      {
        req(input$shinyalert)
        load(paste(input$dropdown_dataset,".Rdata",sep=""))
        react(list(test=test,data=data))
      })


    observeEvent(input$button_dataset, {
      shinyalert(title = "Are you sure?",
                 text = "This action can take a while",
                 type = "warning",
                 closeOnEsc = TRUE,
                 closeOnClickOutside = TRUE,
                 showCancelButton = TRUE,
                 showConfirmButton = TRUE,
                 confirmButtonText = "OK",
                 confirmButtonCol = "#AEDEF4",
                 cancelButtonText = "Cancel",
                 inputId = "shinyalert",
                 callbackR = function(x){
                   if(x){
                     showModal(modalDialog("Loading...", footer=NULL))
                     print(paste(input[["dropdown_dataset"]],sep=""))
                     removeModal()
                   }
                 }
      )
    })
    output$test_text <- renderText(react()$test)
    output$test_plot <- renderPlot(plot(react()$data))
  }
)

Upvotes: 0

Tyler Smith
Tyler Smith

Reputation: 328

I changed the initialization of react_data. You should get rid of the load from your global file. This way the dataset can be garbage collected when you switch. Otherwise, it will exist in .GlobalEnv forever.

Try this server:

shinyServer(
  function(input, output, session) {

    react_data <- reactiveVal()
    react_data(local({load("DatasetNumber1.Rdata"); data}))

    observeEvent(
      input$shinyalert,
      {
        req(input$shinyalert)
        load(paste(input$dropdown_dataset,".Rdata",sep=""))
        react_data(data)
      })


    observeEvent(input$button_dataset, {
      shinyalert(title = "Are you sure?",
                 text = "This action can take a while",
                 type = "warning",
                 closeOnEsc = TRUE,
                 closeOnClickOutside = TRUE,
                 showCancelButton = TRUE,
                 showConfirmButton = TRUE,
                 confirmButtonText = "OK",
                 confirmButtonCol = "#AEDEF4",
                 cancelButtonText = "Cancel",
                 inputId = "shinyalert",
                 callbackR = function(x){
                   if(x){
                     showModal(modalDialog("Loading...", footer=NULL))
                     print(paste(input[["dropdown_dataset"]],sep=""))
                     removeModal()
                   }
                 }
      )
    })
    output$test_text <- renderText(test)
    output$test_plot <- renderPlot(plot(react_data()))
  }
)

Upvotes: 2

Related Questions