I have created a module which takes a data.frame and displays it in a DTOutput. When the user changes the selected row it returns the row number of that row. If I use a reactive data.frame as the input to my module, then to access the returned value I seem to have to use two pairs of brackets. I am sure this should not be necessary, but can't seem to find any other way of doing it. Where am I going wrong?
This is my module:
library(shiny)
library(DT)
#' Datatable output for displaying transactions
#'
#' @param id Namespace (char)
#'
#' @return fluidRow ui containing DTOutput
transactions_ui <- function(id){
fluidRow(
DT::DTOutput(
NS(id, "DT_transactions")
)
)
}
#' transaction module server-side processing
#'
#' @param id character Module Namespace id
#' @param transactions_df data.frame containing transaction details
#'
#' @return list
#' "selected_row" the currently selected row (int)
#' "transactions_df" the transactions data.frame
transactions_server <- function(id, transactions_df){
moduleServer(id, function(input, output, session){
reactive_row_selected <- reactiveVal(1)
output$DT_transactions <- DT::renderDT(
{
datatable(
data = transactions_df,
editable = TRUE,
selection = list(mode = "single", selected = reactive_row_selected())
)
}
)
reactive({
req(nrow(transactions_df)>0)
input$DT_transactions_rows_selected
})
})
}
And this is my testing function:
library(tibble)
transactions_demo <- function(){
datafile <- "test.rds"
reactive_transactions_df <- reactiveVal(new_tibble(list("Category" = c("A", "B"))))
ui <- fluidPage(
transactions_ui("current"),
fluidRow(
actionButton("change_value", "Change")
)
)
server <- function(input, output, session){
sel_row <- reactiveVal()
observeEvent(
reactive_transactions_df(),
sel_row(transactions_server("current", transactions_df = reactive_transactions_df()))
)
observeEvent(
input$change_value,{
print(sel_row()()) # why do I need 2 brackets here?
df <- reactive_transactions_df()
df[sel_row()(),]$Category <- c("C")
reactive_transactions_df(df)
}
)
}
shinyApp(ui, server)
}
It achieves what I want I just don't understand why I need the double brackets ()() to accesss the return value from the module.