Memory retaining in ShinyApp

Respected Sir/Madam,

I am just 12 days old to Shinyapp.I'm working on a shiny app where the users can input into a rHandsontable in one column and get the desired values in other column . This works fine. When I rerun the program it shows the default values and the user inputted values is not retained. But I wish the input-data to be saved with save changes action button, so that when I reload the app, the user input is remembered and shown again. I have been looking at this example, but I am not able to get it implemented correctly. Please do help me with this question and please do post a simple code.

Hi @Aviansh, can you post a reproducible example of your code? So, we can see why it's not working.

Btw, have you seen the examples in the rhandsontable package itself?

1 Like

Respected Mr.Ginberg,

I have written the basic code,but it doesn't include the code for saving the values, since I didn't know how to proceed with the code for saving the values within table. However I will post my code. Please do have a look into it and help me with the query.

thanking you,

your's sincerely,
Avinash Shanmugam

library(shiny)
library(shinydashboard)
library(rhandsontable)

header<-dashboardHeader()
      
sidebar <- dashboardSidebar()
      
   
#Creation of Tabs
body <- dashboardBody( 
   
  tabBox( width=12,
            
  
      tabPanel("Table",
                    
                     rHandsontableOutput("tabl_l1"),
                     br(),
                     br(),
                     actionButton("save","Save changes")
            ),
      
            tabPanel("Demand/Capacity Plot",
                     plotOutput("dc","Demand Capacity Plot",width="50%", height="700px")
            )
     )
  )
  
  ui <- dashboardPage(header,sidebar=sidebar,body=body)
  
  table_l1<- data.frame(Months=1:14,Bt_existing=numeric(14),Output_hr=numeric(14),stringsAsFactors = FALSE)

  server <- function(input, output, session){
  
  prev_tabl_l1 <-  reactive({table_l1})
  
  aftch_tabl_l1<- reactive({
    
    if (is.null(input$tabl_l1)){
      
      return(prev_tabl_l1())
      
    } else if(!identical(prev_tabl_l1(),input$tabl_l1)){
      
      table_l1<-as.data.frame(hot_to_r(input$tabl_l1))
      
      table_l1[,3]<-3600/table_l1[,2]
   
      table_l1 
    }
  })
  
output$tabl_l1<- renderRHandsontable({
    
    rhandsontable (aftch_tabl_l1(),rowHeaders =c("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec","Year 1","year 2"),width= 500, height=200,selectCallback = TRUE)%>%
      hot_table(rowHeaderWidth = 200)%>%
      hot_col(1,readOnly = TRUE)
     
    })
  
}
  
shinyApp(ui=ui,server=server)

@Aviansh you did not define the behaviour for the save button. If you just want to save the data to disk, you can do it like this

library(shiny)
library(shinydashboard)
library(rhandsontable)

header<-dashboardHeader()

sidebar <- dashboardSidebar()

#Creation of Tabs
body <- dashboardBody(
  tabBox( width=12,
          tabPanel("Table",
                   rHandsontableOutput("hot"),
                   br(),
                   br(),
                   actionButton("save","Save changes")
          ),
          
          tabPanel("Demand/Capacity Plot",
                   plotOutput("dc","Demand Capacity Plot",width="50%", height="700px")
          )
  )
)

ui <- dashboardPage(header,sidebar=sidebar,body=body)

table_l1<- data.frame(Months=1:14,Bt_existing=numeric(14),Output_hr=numeric(14),stringsAsFactors = FALSE)

server <- function(input, output, session){
  
  prev_tabl_l1 <- reactive({table_l1})
  aftch_tabl_l1<- reactive({
    
    if (is.null(input$hot)){
      return(prev_tabl_l1())
      
    } else if(!identical(prev_tabl_l1(),input$hot)){
      table_l1<-as.data.frame(hot_to_r(input$hot))
      table_l1[,3]<-3600/table_l1[,2]
      table_l1 
    }
  })
  
  output$hot <- renderRHandsontable({
    rhandsontable (aftch_tabl_l1(),rowHeaders =c("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec","Year 1","year 2"),width= 500, height=200,selectCallback = TRUE) %>%
      hot_table(rowHeaderWidth = 200) %>%
      hot_col(1,readOnly = TRUE)
  })
  
  observeEvent(input$save,{
    hot <- isolate(input$hot)
    if(!is.null(hot)){
      fname = tempfile(fileext = ".csv")
      write.csv(hot_to_r(hot), fname)
      print(paste("Saved to", fname))
    }
  })
}

shinyApp(ui=ui, server=server)

Respected Ginberg,

Thank you very much for the response and I am very sorry for my late reply. I would like you to ask one more thing. If I want to store it in a database/server(remote storage) and retrieve the previously edited inputs every-time when a user uses my App, will the syntax be similar to the data Storage or is it entirely different. I do have a question about the previous code.
hot<- isolate(input$hot) --------- is this a kind of a inbuilt syntax or it is that you are isolating a table and defining it to the variable hot?
Sorry to trouble you with so many Questions.

Thanking you,

Your's sincerely,
Avinash Shanmugam

@Aviansh it's just assigning the contents of the table to the variable. You can remove the isolate function call,I realized. It can be used to prevent a trigger of a reactive expression, but since this is an observeEvent it's not needed. See here for a better explanation with example

Yes, you can replace the file storage for a database storage, the same approach can be used

Respected Ginberg,

Thank You so much for your kind response. This means if I could write values out of shiny, then I can also read values into shiny. What I mean is when the user inputs the data and closes the app and again opens it , he/she might be able to look at the previous data entered. Is that correct? But thank you so much. Since I am new to this platform I could not capture the concept well.
Thanking you,

Your's sincerely,
Avinash

@Aviansh, that's right. Just make sure you, that when you are starting the app, the initial data (table_l1 in your example) is loaded from the storage instead of hardcoded

Respected Mr. Ginberg,

Thank you very much. I think read.csv function should do the job. Once I am able to do that I will surely post you with my Progress. It was such a kind gesture from you.
Thanking you,
Your's sincerely,
Avinash Shanmugam

Respected Ginberg,

Just a question. I have saved the inputted values into a seperate file as u suggested and i understand to load it back read.csv is needed. Will read.csv will directly paste the values into shiny in rhandsontable form or it will just read the values, Which means that I should write a code for pasting the values into the respective columns? Sorry to post you with more questions

@Aviansh the rhandsontable data argument can be a data.frame, data.table or matrix. The read.csv function outputs a data.frame so that should work fine together.
Do you know that you can see function documentation in R with ? syntax?
Good luck.

1 Like