Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DT Editing in Shiny application with client-side processing (server = F) throws JSON Error

I have a Shiny Server application in which the user can edit a datatable, after which some reactive summary statistics update accordingly. I am hosting this app on a fairly slow framework, which is why I want to use client-side processing for the DT rendering, i.e. server = F passed to DT::renderDataTable. Let me break down the main points of my problem:

  • The code is fully operational when server = T is passed.

  • When passing server = F, the browser throws the following error message when the user edits a cell in the DT:

DataTables warning: table id=DataTables_Table_5 - Invalid JSON response. For more information about this error, please see http://datatables.net/tn/1

An interesting thing is that when this error window is dismissed, the dependent summary statistics update correctly according to the edit, and the Shiny app carries on. Hence, everything works except for the error. I should note that I visited the site referred to in the error without becoming any wiser.

Reproducible example below:

library(shiny)
library(DT)

dt = data.frame(V1 = c(1,2), V2 = c(3,4))

server <- function(input, output, session) {

val = reactiveValues(mat = data.table(dt))

output$testDT = renderDataTable({
            DT::datatable(val$mat, editable = TRUE)
}, server = FALSE)

proxy = dataTableProxy('testDT')

observeEvent(input$testDT_cell_edit, {

  info = input$testDT_cell_edit

  str(info)

  i = info$row
  j = info$col
  v = info$val

  if (j == 1){

  val$mat$V1[i] = DT::coerceValue(v, val$mat$V1[i])
  replaceData(proxy, val$mat, rownames = FALSE)

  }

})


}

ui <- fluidPage(
  dataTableOutput('testDT') 
)

shinyApp(ui, server)

Thanks!

like image 371
JDG Avatar asked Sep 26 '18 13:09

JDG


1 Answers

It's has been answered on the Github thread and I'm sharing my answer here.

Probably it's not documented clearly. It has nothing to do with the editing. It's because replaceData() calls reloadData(), which requires the server-side processing mode. See ?reloadData().

reloadData() only works for tables in the server-side processing mode, e.g. tables rendered with renderDataTable(server = TRUE). The data to be reloaded (i.e. the one you pass to dataTableAjax()) must have exactly the same number of columns as the previous data object in the table.

like image 90
Shrek Tan Avatar answered Nov 15 '22 07:11

Shrek Tan