rshinygolem

Golem modules doesn't work in server side


I have been working in a Shiny app and now I'm trying to put it in modules with Golem.

My app_ui.R:

#' The application User-Interface
#'
#' @param request Internal parameter for `{shiny}`.
#'     DO NOT REMOVE.
#' @import shiny
#' @noRd
app_ui <- function(request) {
   tagList(# Leave this function for adding external resources
      golem_add_external_resources(),
      # Your application UI logic
      fluidPage(
         theme = shinythemes::shinytheme("united"),
         navbarPage(
            # theme = "cerulean",  # <--- To use a theme, uncomment this
            "App Cool Name",
            tabPanel(
               "Inicial",
               h5("Dados Gerais"),
               fluidRow(
                  shinydashboard::valueBoxOutput(outputId = "data_msg",
                                                 width = "3"),
                  shinydashboard::valueBoxOutput(outputId = "data_groups",
                                                 width = "3")
                  
               ))))
)
}

#' Add external Resources to the Application
#'
#' This function is internally used to add external
#' resources inside the Shiny application.
#'
#' @import shiny
#' @importFrom golem add_resource_path activate_js favicon bundle_resources
#' @noRd
golem_add_external_resources <- function() {
  add_resource_path(
    "www",
    app_sys("app/www")
  )

  tags$head(
    favicon(),
    bundle_resources(
      path = app_sys("app/www"),
      app_title = "reprex"
    )
    # Add here other external resources
    # for example, you can add shinyalert::useShinyalert()
  )
}

my app_server.R:

#' The application server-side
#'
#' @param input,output,session Internal parameters for {shiny}.
#'     DO NOT REMOVE.
#' @import shiny
#' @noRd
app_server <- function(input, output, session) {
  # Your application server logic
   con <- DBI::dbConnect(drv = RSQLite::SQLite(),
                         dbname = "data-raw/data_base.db")

   output$data_msg <- shinydashboard::renderValueBox({
      data_msg <-
         as.character(
            DBI::dbGetQuery(
               con,
               "select count(*) as msg
                                                from cool_name
                                              where network IN ('data')"
            )
         )
      shinydashboard::valueBox(
         value = data_msg,
         subtitle = "Nº Mensagens",
         color = "yellow",
         width = "3 col-lg-2"
      )
   })

  

   output$data_group <- shinydashboard::renderValueBox({
      data_group <-
         as.character(
            DBI::dbGetQuery(
               con,
               "select sum(a.cnt)
                                      from (
                                              select count(distinct(group_id)) as cnt
                                              from cool_name
                             where network IN ('telegram')
                                              group by group_id
                                           ) as a"
            )
         )

      shinydashboard::valueBox(
         value = data_group,
         subtitle = "Nº de Grupos",
         color = "yellow",
         width = "3"
      )
   })

}

This works fine! But when I put it in modules, it doesn't work at all.

I use the golem::add_modules("test").

My mod_test.R:

#' test UI Function
#'
#' @description A shiny Module.
#'
#' @param id,input,output,session Internal parameters for {shiny}.
#'
#' @noRd
#'
#' @importFrom shiny NS tagList
mod_test_ui <- function(id){
  ns <- NS(id)
  tagList(
     # Frontpage - boxes - start -----------------------------------------------
     shinydashboard::valueBoxOutput(outputId = "data_msg",
                                    width = "3"),
     shinydashboard::valueBoxOutput(outputId = "data_groups",
                                    width = "3")
     
  )
}

#' test Server Functions
#'
#' @noRd
mod_test_server <- function(id){
  moduleServer( id, function(input, output, session){
    ns <- session$ns

    con <- DBI::dbConnect(drv = RSQLite::SQLite(),
                          dbname = "data-raw/data_base.db")
    
    output$data_msg <- shinydashboard::renderValueBox({
       data_msg <-
          as.character(
             DBI::dbGetQuery(
                con,
                "select count(*) as msg
                                                from cool_name
                                              where network IN ('data')"
             )
          )
       shinydashboard::valueBox(
          value = data_msg,
          subtitle = "Nº Mensagens",
          color = "yellow",
          width = "3 col-lg-2"
       )
    })
    
    
    
    output$data_group <- shinydashboard::renderValueBox({
       data_group <-
          as.character(
             DBI::dbGetQuery(
                con,
                "select sum(a.cnt)
                                      from (
                                              select count(distinct(group_id)) as cnt
                                              from cool_name
                             where network IN ('telegram')
                                              group by group_id
                                           ) as a"
             )
          )
       
       shinydashboard::valueBox(
          value = data_group,
          subtitle = "Nº de Grupos",
          color = "yellow",
          width = "3"
       )
    })
    
  })
}

## To be copied in the UI
# mod_test_ui("test_1")

## To be copied in the server
# mod_test_server("test_1")

When I replace the full code in ui and server by mod_test_ui("test_1") and mod_test_server("test_1"). I doesn't work!

BUT if I replace only the ui parts by mod_test_ui("test_1"), this works fine. What I'm missing in my server?


Solution

  • You have to use the namespace (ns) in the UI module. Enclose each id with ns():

    mod_test_ui <- function(id){
      ns <- NS(id)
      tagList(
         # Frontpage - boxes - start -----------------------------------------------
         shinydashboard::valueBoxOutput(outputId = ns("data_msg"),
                                        width = "3"),
         shinydashboard::valueBoxOutput(outputId = ns("data_groups"),
                                        width = "3")
         
      )
    }