Is it possible to create a reactive field in class or a class which notify app when her field change ?
I got this class which is a model for my shinyApp:
CatalogModele <- setRefClass("CatalogModele",
fields = list(catalogs = "list"),
methods = list(
initialize = function(catalogs_args = list()) {
catalogs <<- catalogs_args
},
add_catalog = function(key, value) {
catalogs[[key]] <<- value
}
)
)
I would like to update some shiny widgets when i use "add_catalog()" on my global object. I tried this :
catalogModele <<- reactive({CatalogModele()})
on.exit(rm(catalogModele, pos = ".GlobalEnv"))
But nothing happen when i observe my variable :
observeEvent(catalogModele(), {
str(catalogModele()$catalogs)
})
Thanks for reading.
I use R6
classes for a similar purpose. Maybe looking at this will help you develop a similar design for reference classes
library(R6)
library(shiny)
myClass <- R6Class(
public = list(
catalogs = reactiveValues(),
add_catalog = function(key,value){
self$catalogs[[key]] <- value
}
)
)
A = myClass$new()
shinyApp(
fluidPage(
inputPanel(
textInput('key', 'key'),
textInput('value', 'value'),
actionButton('go', 'add')
),
verbatimTextOutput('textOut')
),
function(input, output, session){
observeEvent(input$go,
{ A$add_catalog(input$key, input$value) }
)
output$textOut <- renderPrint({
reactiveValuesToList(A$catalogs)
})
}
)
EDIT: Here is an actual working solution. I just wrapped the member reactives
from the R6
class into a list and made it a member of the reference class.
CatalogModele <- setRefClass(
"CatalogModele",
fields = list(catalogs = "list"),
methods = list(
initialize = function(catalogs_args = list()) {
catalogs <<- list(reactives = reactiveValues())
},
add_catalog = function(key, value) {
catalogs$reactives[[key]] <<- value
},
get_catalogs = function()
reactiveValuesToList(catalogs$reactives)
)
)
B = CatalogModele()
shinyApp(
fluidPage(
inputPanel(
textInput('key', 'key'),
textInput('value', 'value'),
actionButton('go', 'add')
),
verbatimTextOutput('textOut')
),
function(input, output, session){
observeEvent(input$go,
{ B$add_catalog(input$key, input$value) }
)
output$textOut <- renderPrint(B$get_catalogs())
}
)
In both cases, it is advisable to just make certain parts of your class reactive . Otherwise, you might encounter very poor performance in your apps.