R Shiny nested modules, input unavailable

Cross post from SO: R Shiny nested modules, input unavailable - Stack Overflow

I am trying to build an shiny application for simple data entry using 2 nested modules. The user supplies a dataframe with particular column types, and the application will allow you to add more rows to it. The first module ("input") will create the input widget based on the column types. The second module ("table") displays the table, and allows additional rows to be added. I have nested module 1 within module 2 as a modal popup.

The problem I am having is I cannot access the input in the first module ("input"). I can see the names of the variables, and that is a ReactiveValues object, but everything is NULL.

Any help would be greatly appreciated (apologies for the long code, it is the shortest reproducible example I could make).

library(shiny)
library(DT)
library(data.table)

df<-data.frame(
  a=as.character(NA),
  b=as.numeric(NA)
)


# Module for creating input fileds ----------------------------------------
input_UI<-function(id,df) {
  ns<-NS(id)
  
  tagList(
    lapply(1:ncol(df),function(x){
    switch(class(df[,x][[1]]),
           numeric=numericInput(
             inputId = ns(paste0(colnames(df)[x])),
             label=paste0(colnames(df)[x]),
             value=0
           ),
           character=textInput(
             inputId = ns(paste0(colnames(df)[x])),
             label=paste0(colnames(df)[x]),
             value=""
           )
    )
  })
  )
}

input_server<-function(id,df,debug=F) {
  moduleServer(
    id,
    function(input, output, session) {
      dataframe=reactive({
        if (debug==T){
          browser() #this is where I am having trouble accessing input
        }
        inputlist<-lapply(1:ncol(df), function(x){
          switch(class(df[,x][[1]]),
                 numeric=as.numeric(input[[paste0(id,"-",colnames(df)[[x]])]]),
                 character=as.character(input[[paste0(id,"-",colnames(df)[[x]])]])
                 )
        })

        df_temp<-data.frame(inputlist)
        colnames(df_temp)=colnames(df)
        df_temp
      })
      return(dataframe)
    }
  )
}


# module for showing data, and adding rows --------------------------------
table_UI<-function(id){
  ns<-NS(id)
  tagList(
    uiOutput(ns("MainBody_dataEntry"))
  )
}

table_sever<-function(id,df){
  moduleServer(
    id,
    function(input, output, session) {
      ns <- session$ns
      
      data_vals<-reactiveValues()
      data_vals$Data<-df
      
      output$MainBody_dataEntry<-renderUI({
        fluidPage(
          hr(),
          column(6,offset = 6,
                 actionButton(inputId = ns("Add_row_head"),label = "Add", class="btn-primary")
          ),
          column(12,dataTableOutput(ns("Main_table"))),
        ) 
      })
      
      output$Main_table<-renderDataTable({
        DT=data.table(data_vals$Data)
        datatable(DT)
      })
      
      observeEvent(input$Add_row_head, {
        showModal(modalDialog(title = "Add a new row",
                              input_UI(ns("add_row"),df=data_vals$Data),
                              easyClose = F,
                              footer = actionButton(ns("confirm_newrow"), "Add item") ))
        
      })
      observeEvent(input$confirm_newrow, {
        datafile <- input_server(ns("add_row"),df=data_vals$Data,debug=T)
        new_row=data.frame(datafile())
        data_vals$Data<-rbind(data_vals$Data, new_row )
        removeModal()
      })
      
    }
  )
}

ui<-shinyUI(fluidPage(
  table_UI("test")
))

server<-shinyServer(function(input, output, session){
  table_sever("test",df)
})


shinyApp(ui, server)

I have not tested it in detail, but I have the habit to insert

stopifnot(is.reactive(df)) in all servers following the suggestion of hadley in
https://mastering-shiny.org/scaling-modules.html#server-inputs

Inspecting your code visually makes me believe that some reactive() is missing.

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

If you have a query related to it or one of the replies, start a new topic and refer back with a link.