glin / reactable

Interactive data tables for R
https://glin.github.io/reactable
Other
612 stars 79 forks source link

Suggestion: Accepting `NULL` as an input #288

Open daattali opened 1 year ago

daattali commented 1 year ago

When building shiny apps, sometimes you have a dataset that starts off as NULL. Often we use req() to avoid passing that data into the reactable(), but it would also be good if reactable() didn't fail when receiving null.

Example:

library(shiny)

ui <- fluidPage(
  reactable::reactableOutput("table")
)

server <- function(input, output, session) {
  output$table <- reactable::renderReactable({
    reactable::reactable(NULL)
  })
}

shinyApp(ui, server)

Rather than an error, I would expect the above app to just not show a table (for reference, DT works this way)

glin commented 1 year ago

Would returning NULL from renderReactable() work? Like you could do a NULL check on the dataset, then return NULL if so. I'm not sure if returning NULL is a documented thing for Shiny's render functions, but it does seem to work and render an empty element without errors:

library(shiny)

ui <- fluidPage(
  reactable::reactableOutput("table")
)

server <- function(input, output, session) {
  output$table <- reactable::renderReactable({
    data <- NULL
    if (is.null(data)) {
      return(NULL)
    }

    reactable::reactable(data)
  })
}

shinyApp(ui, server)

Otherwise, having reactable() or any other htmlwidget take NULL as a data input doesn't really seem intuitive to me, and I'm not sure what to expect if that was valid. Maybe an empty element, or an empty table with manually-specified columns, or a widget with no table but the pagination bar still there? I think requiring the data to be a data frame would be the most predictable/consistent behavior, and definitely recommend using req() or conditional UI (or returning NULL from the render function if that works) to hide the table until there's valid data.

Or alternatively, it is possible to render an empty table with an empty data frame if you know the columns up front, e.g.:

library(shiny)

ui <- fluidPage(
  reactable::reactableOutput("table")
)

server <- function(input, output, session) {
  data <- reactive(data.frame(num = numeric(0), chr = character(0)))

  output$table <- reactable::renderReactable({
    reactable::reactable(data())
  })
}

shinyApp(ui, server)
daattali commented 1 year ago

As far as I know there's no official documentation about NULL values in render functions, but I just find it convenient that some functions "just work" and do what I want them to do when given NULL.

If it seems like it'll complicate the internals and create messy code then don't worry about it, it was merely a suggestion to think about and it looks like you've now thought about it :)