R shiny app modules

I am trying to implement shiny modules as I realized the server and ui files were just about to implode.Here is my understanding and I have three files UI.r, server.r and module.r

But when I try it I get the following error. Could someone tell me what is wrong with the implementation of shiny modules here.

##UI.r
library(shiny)
library(shinydashboard)
library(plotly)
source("module.R")

sidebar <- dashboardSidebar(sidebarMenu(
  menuItem("Topline",tabName = "topline")))

body <-   ## Body content
  dashboardBody(tabItems(
    tabItem(tabName = "atc_topline",
                      fluidRow( tags$br(),
                      column(3, uiOutput("class_level"))),
                      fluidRow(chartTableBoxUI(id = "topline")) # render the tabBox inside a fluidRow
  ))
# Pt them together into a dashboardPage
dashboardPage(
  dashboardHeader(title = "Scorecard"),
  sidebar,
  body
)

Server.r

## Server.r
library(shiny)
library(dplyr)
library(knitr)
library(kableExtra)
library(plotly)
library(tidyr)
library(zoo)
library(plyr)
library(tidyverse)
source("module.R")

shinyServer(function(input, output) {
    MyData <- read.csv(file="ldb_data.csv", header=TRUE, sep=",")
    callModule(chartTableBox, id = "topline", data = MyData, class_group = "ATC Topline")

})

Module

##module.r
chartTableBoxUI <- function(id, div_width = "col-md-9") {
  ns <- NS(id)
  
  div(class = div_width,
      tabBox(
        width = 12,
        title = id,
        # tabPanel(icon("bar-chart"),
        #          plotlyOutput(ns("chart") )
        # ),
        tabPanel(icon("table"),
                 DT::dataTableOutput(ns("table")))
      ))
  
}

chartTableBox <-
  function(input, output, session, data, class_group) {
    module_data <- data %>% filter(category == class_group)
    
    module_data$Month_considered  <-as.character(module_data$Month_considered)
    module_data$Month_considered[which(module_data$Month_considered == "2/1/18")] <-"Feb-18"
    module_data$Month_considered  <-as.factor(module_data$Month_considered)
    
    
    
    # Drop-down selection box for which Classification Level to be selected
    output$class_level <- renderUI({
      selectInput(
        "selected_class",
        label = h4("Classification Level"),
        choices = list(
          "11 " = "1",
          "22 " = "2",
          "33" = "3",
          "44" = "4"
        )
      )
    })

    #### TOPLINE #####
        a <- reactive({
      module_data %>%
        filter(Tab == input$selected_class) %>%
        #filter(Classification_Level == input$selected_class & Primary_family == input$selected_product & Metric_name == input$selected_metric) %>%
        mutate(`ATC_Count` = Metric_Value) %>%
        mutate(`pct` = as.numeric(as.character(Metric_Value)) * 100) %>%
        select(Month_considered, `pct`) %>%
        group_by(Month_considered)
    })
    
    #arrange(Month_considered)
    
    b <- reactive({
      module_data %>%
        filter(Tab == input$selected_class) %>%
        #filter(Tab == "ATC Count" & Classification_Level == input$selected_class & Primary_family == input$selected_product) %>%
        group_by(Month_considered) %>%
        mutate(`ATC_Count` = Metric_Value) %>%
        select(Month_considered, `ATC_Count`)
    })
    #arrange(Month_considered)
    
    dt_data <- reactive({
      (inner_join(a(), b()))
    })
    
    
    # output$chart <- renderPlotly({
    #
    #   plot_ly(dt_data(), x = ~Month_considered, y = ~pct, type = 'scatter',mode = 'marker',fill = 'tozeroy',line = list(color = 'rgb(205, 12, 24)', width = 4))
    #
    # })
    
    output$table <- renderDataTable({
      DT::datatable(
        dt_data(),
        style = "bootstrap",
        class = "display",
        options = list(scrollX = TRUE, dom = 't')
      ) %>%
        formatPercentage('percent', 0)
      
    })
    
  }

Error:

Warning: Error in filter_impl: Evaluation error: object 'category' not found.
  69: <Anonymous>
Error in filter_impl(.data, quo) : 
  Evaluation error: object 'category' not found.

Your setup looks solid. The error message highlights line 69 and filter / category. That makes me suspicious that this line is your problem:

module_data <- data %>% filter(category == class_group)

If the category variable does not exist on data, then this is the type of error that will be thrown. If this category does exist, then there is always the chance that the module is firing before the data is ready / passed in.

If / when this is the case in Shiny development, something like req(data) will silently stop the errors until data is resolved into an appropriate object. (Best to file this away in useful tools to avoid the occasional pain of reactivity!).

1 Like