” Error: object ‘output’ not found ” returned from downloadHandler reactive table in R Shiny

I am working on a side project for a budget template as a Shiny app. I have everything else worked out, but I’m getting stuck on implementing a downloadButton and downloadHandler feature to download the transaction table (Table 2) from the main panel as a CSV file. I think my biggest issue here is that I’m working with a reactive table where I can add and remove rows at whim. I watched several YouTube videos and read as many SO questions as I could find, but I’m not making anymore headway. The best I could try was adding another renderTable function right before the downloadHandler. Also, I noticed that changing tableOutput to dataTableOutput (avoided since deprecated) or renderDT completely removes table1 and table2 when the app is ran. Could this be related? What can I do to fix this issue? I just started using Shiny this week, so all help is greatly appreciated. Thanks!

Below is my code:

##### Necessary packages. #####
library(shiny)
if(!require(shinyjs)) { install.packages("shinyjs")}
if(!require(shinyWidgets)) { install.packages("shinyWidgets")}
library(tidyverse)
if(!require(writexl)) { install.packages("writexl")}

##### Creating the app. #####

# Custom functions to add a delete button to each transaction table row.
# Define UI for application that creates an interactive budget. 
ui <- fluidPage(

# Application title
    titlePanel(h1("50-30-20 Interactive Budget", align = "center")),

# Sidebar with fields for income and transaction information and buttons to
# reset information or add it to the table. Also includes table displaying
# budget budget balances.
    sidebarLayout(
        sidebarPanel(
          shinyjs::useShinyjs(),
          id = "side_panel",
          shinyWidgets::autonumericInput(
            "inc",
            "Enter your monthly income:",
            min = 0,
            value = 1000.00,
            decimalPlaces = 2
            ),
          actionButton("button", "Reset Monthly Income"),
          tableOutput("table1"),
          tags$hr(),
            
          dateInput(
            "date", 
            "Enter the transaction date:", 
            format = "mm-dd-yyyy",
            value = "06-25-2024"
              ),
          textInput("desc", "Enter the transaction description:"),
          selectInput(
            "type",
            "Select the transaction category:",
            choices = c("Bills", "Discretionary", "Savings")
            ),
          shinyWidgets::autonumericInput(
            "amt",
            "Enter the transaction amount:",
            min = 0,
            value = 0.00,
            decimalPlaces = 2
          ),
          actionButton("button2", "Reset Transaction Information"),
          actionButton("button3", "Add Information to Table"),
          actionButton("button4", "Remove Previous Row"),
          downloadButton("downloadData","Download Tables")
        ),
    
# Display an explanation of the budget and display the transaction table.
        mainPanel(
           p("The 50-30-20 budget divides monthly income into categories of 50% 
             of income for bills and fixed expenses, 30% for discretionary 
             purchases, and 20% for savings. Please enter your monthly income 
             and the transaction date, description, type (Bills, Discretionary, 
             or Savings), and amount below. The app will calculate each 
             category's starting and remaining monthly balance. Resetting
             the app will clear all information."),

           
           tableOutput("table2")
        )
    )
)

# Define server logic required to render fields, buttons, and tables.
server <- function(input, output, session) {
  


# Assign functionality to transaction table. Since button3 and button4 directly
# affect the xyTable, assign functionality here instead of with the other buttons.
  xyTable <- reactiveVal(
    tibble(Date = ymd(), Description = character(), Category = character(), Amount = numeric())
  )
  
  observeEvent(input$button3, {
    xyTable() %>%
      add_row(
        Date = input$date,
        Description = input$desc,
        Category = input$type,
        Amount = input$amt
      ) %>%
      xyTable()
  }
  )
  
  observeEvent(input$button4,{ xyTable() %>% filter(row_number() < n()) %>% xyTable()})

  output$table2 <- renderTable(xyTable() %>% mutate(Date = format(Date, "%m-%d-%Y")), width = "auto")  
  
# Assign functions to the buttons.  
  observeEvent(input$button, {shinyjs::reset("inc")})
  observeEvent(input$button2,{
    updateDateInput(session, "date", value = "06-25-2024")
    updateTextInput(session, "desc", value = "")
    updateSelectInput(session, "type", choices = c("Bills", "Discretionary", "Savings"))
    updateAutonumericInput(session, "amt", value = 0.00)
  })

# Create the starting and remaining balance columns.
  output$table1 <- renderTable(
    tibble(
      Category = c("Bills", "Discretionary", "Savings"),
      `Starting Balance` = c(input$inc * 0.5, input$inc * 0.3, input$inc * 0.2)
        
      )
  )

}



# Write tables to Excel file for download button.
output$table2 <- renderTable({T2()})

output$downloadData <- downloadHandler(
  filename = "50-30-20Budget.csv",
  content = function(file) {
    write.csv(T2(), file)
  }
)

# Run the application 
shinyApp(ui = ui, server = server)

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật