Use reactiveValues with modules

Hello,

I can´t figure out a detail for which I have added a simplified reproducible example below.
I know this is similar to several other issues posted about modules and reatives, but I can´t get this to work nonetheless.

I am working on an app where some value has the potential to be changed from several parts of the app. Say by clicking a row in one of many different dataTables some kind of ID value gets pulled into that value.
So I figured it´s best to use a reactiveValues - Container.

This is already implemented in the repexp below.

Now I managed to successfully use that filter for reactively changing a dataTableOutput that is programmed directly in the ui / server functions.
But I don´t get the reactiveness to work with the same dataTableOutput generated by a module.

Can somebody please offer some advice?

require(shiny)

# 1) Setup ----
# Base data ----
mycars <- rownames_to_column(mtcars)

# Reactive environment ----
rvals <- reactiveValues()
rvals$carfilter <- NULL



# 2) Module for showing datatable ----
# ui part
dataviewUI <- function(id) {
	ns <- NS(id) # Create a namespace function using the provided id

	tagList(
		dataTableOutput(
			outputId = ns("mod_data")
		)
	)
}

# server part
dataview <- function(input, output, session, base_data) {

	# build and render data table
	output$mod_data <- renderDataTable(
		base_data,
		selection = "single",
		rownames = FALSE
	)

	#row click event: change rvals$carfilter to clicked car
	observeEvent(input[["mod_data_rows_selected"]], {
		row <- input[["mod_data_rows_selected"]]
		rvals$carfilter <- base_data[row, "rowname"]
	})
}



# 3) Define UI ----
ui <- navbarPage(
	id ="mynavbar" , 
	title = "NAVBAR",
	tabPanel("Cars",
	 			 fluidPage(
	 			 	titlePanel("Car info"),
	 			 	dataviewUI(id = "all_cars")
	 			 )
	),
	tabPanel(
		"Single Car Viewer",
 		 fluidPage(
 		 	titlePanel("Single Car data"),
 		 	dataTableOutput("single_car_fixed"),
 		 	dataviewUI(id="single_car_module")
 		 )
	)
)



# 4) Define Server ----

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

	# All car view
	callModule(
		module=dataview,
		id="all_cars",
		base_data = mycars
	)

	# Single car view
	mydata <- reactive({
		mycars %>% filter(rowname %in% as.character(rvals$carfilter))
	})

	#single car view FIXED --> WORKS
	output$single_car_fixed <- renderDataTable({mydata()})

	# single car view MODULE --> WILL ONLY REACT TO FIRST TIME OF SWITCHING TO SINGLE VIEW TAB
	callModule(
		module=dataview,
		id="single_car_module",
		base_data = mydata()
	)

}

# 5) Build shiny App ----
shinyApp(ui,server)

Any help would be greatly appreciated for sure!

I wasn't able to solve the problem using reactiveValues.
But after some pondering I found a neater way that I´ll share in principle here in case someone has a similar problem:

Instead of setting a reactiveValue like in the code above

rvals$carfilter <- base_data[row, "rowname"]

I now use the row click event to simply manipulate the value of a text input like so

dataview <- function(input, output, session, base_data, mysession) {
    # [...]
    # in row click event:
    updateTextInput(session=mysession,inputId="carfilter",
        value= as.character(base_data[row, "rowname"]))
    # [...]
}

Note that I didn´t get this to work by using the regular session parameter of the module`s server function but had to introduce a seperate session parameter ("mysession" in the example) and then call the module like so:

callModule(dataview, id="all_cars",base_data = mycars, mysession=session)

Now that input, manipulated using elements generated by potentially many different modules, can be used in a regular reactive expression:

mydata <- reactive({
    mycars %>% filter(rowname %in% input$carfilter)
})

This input will be evaluated in the regular reactive process even though it is hidden from the user (e.g. by simple css display: none), which is a prerequisite in my real application, where the actual identifier used to filter data for a module is a cryptic GUID.

I won't go into using those regular reactive expressions in modules. For that I recommend the "Modularizing Shiny app code" talk at the 2016 Shiny Developers Conference, minute 50 onwards.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.