0

I'm creating an app to keep track of game data and distributes for free since there seems to be a need (read: want) for such a thing. The app takes initial input on how many players there should be and then reactively allows data input for each player. Then, i want to present all the data that has been received as a data table, which is able to be downloaded on the next page.

I have started modularizing my apps recently for cleanliness. Though, for some reason, I cannot get this one to work. I think it is because I am trying to pass renderUI inputs from one module to the next and clearly am not sure how to do so.

The error I am receiving is:

Error in module(childScope$input, childScope$output, childScope, ...) : 
  object 'player_id' not found

Though, I've received many different ones in an attempt to resolve.

For the record, I have checked out: pass renderUI input from one Shiny module to another

and: https://community.rstudio.com/t/modularizing-an-app-with-dynamic-inputs-renderui/1454

which seem to be close...

Here is a very simple example with the modules in the app.R (I source them otherwise).

library(shiny)

######################## -- Data Input Module -- ######################## 
datatrackingUI <- function(id){
  ns <- NS(id)
  fluidPage(
    column(4, offset = 4,
           sliderInput(inputId = ns("players"),
                       label = "How many players do you have?",
                       min = 0,
                       max = 4,
                       value = 4)),
    column(12,
           uiOutput(ns("ui_reactive"))
    )
  )

}

datatracking <- function(input, output, session){
  ns <- session$ns

  output$ui_reactive <- renderUI({
    lapply(seq_len(input$players), function(i){
      column(4,
             wellPanel(
               textInput(inputId = ns("player_id"),
                         label = paste0("Enter the ID for player ", i),
                         placeholder = "Brennan")))})

  })

  df_list <- list(player_id = player_id)
  return(df_list)

}

######################## -- Create Data Table Module -- ######################## 
createTableUI <- function(id){
  ns <- NS(id)

  fluidPage(
    renderUI("some_text_for_now")
  )
}

createTable <- function(input, output, sesssion, df_list){
  ns <- session$ns
  output$some_text_for_now <- renderText({
    print(df_list$player_id())
  })

}



######################## -- Shiny App -- ######################## 
ui <- fluidPage(
  navbarPage("Game",
             tabPanel("Input",
                      hr(),
                      datatrackingUI("create_data")),
             tabPanel("Table",
                      hr(),
                      createTableUI("create_table"))
  )
)

server <- function(input, output, session) {
   df_list <- callModule(datatracking, "create_data")
   callModule(createTable, "create_table", df_list)
}

shinyApp(ui = ui, server = server)

So, for now, I am just trying to show myself that I have output from the renderUI function. I can handle creating datatable/pushing to AWS once I can access inputs!

Any help is appreciated! Or, if you'd like to work with me on the project, it may be fun! Message me for more info.

-Brennan

Brennan Beal
  • 108
  • 7

1 Answers1

1

There are two simple issues in your code:

  • when you define df_list in the module datatracking, you don't use the input so there is nothing reactive. Instead, you should do:
 df_list <- list(
    player_id = reactive(input$player_id)
  )
  • there are 3 s in session when you define the createTable module so you have to correct this typo.

Full working example:

library(shiny)

######################## -- Data Input Module -- ######################## 
datatrackingUI <- function(id){
  ns <- NS(id)
  fluidPage(
    column(4, offset = 4,
           sliderInput(inputId = ns("players"),
                       label = "How many players do you have?",
                       min = 0,
                       max = 4,
                       value = 4)),
    column(12,
           uiOutput(ns("ui_reactive"))
    )
  )

}

datatracking <- function(input, output, session){
  ns <- session$ns

  output$ui_reactive <- renderUI({
    lapply(seq_len(input$players), function(i){
      column(4,
             wellPanel(
               textInput(inputId = ns("player_id"),
                         label = paste0("Enter the ID for player ", i),
                         placeholder = "Brennan")))})

  })

  df_list <- list(
    player_id = reactive(input$player_id)
  )
  return(df_list)

}

######################## -- Create Data Table Module -- ######################## 
createTableUI <- function(id){
  ns <- NS(id)

  fluidPage(
    renderUI("some_text_for_now")
  )
}

createTable <- function(input, output, session, df_list){
  ns <- session$ns
  output$some_text_for_now <- renderText({
    print(df_list$player_id())
  })

}



######################## -- Shiny App -- ######################## 
ui <- fluidPage(
  navbarPage("Game",
             tabPanel("Input",
                      hr(),
                      datatrackingUI("create_data")),
             tabPanel("Table",
                      hr(),
                      createTableUI("create_table"))
  )
)

server <- function(input, output, session) {
  df_list <- callModule(datatracking, "create_data")
  callModule(createTable, "create_table", df_list = df_list)
}

shinyApp(ui = ui, server = server)
bretauv
  • 7,756
  • 2
  • 20
  • 57
  • Thanks for the response! Though, it still doesn't print anything on the "Table" page when I place id values in the inputText? – Brennan Beal May 27 '20 at 13:38
  • Okay... I've fixed it on original. So, all good! I must have been looking at it for far too long when I posted this!! Thanks for the careful eye and good catch. – Brennan Beal May 27 '20 at 14:13