Home > other >  r-shiny send multiple json files to javascript frontend (ag-grid) in the same callback
r-shiny send multiple json files to javascript frontend (ag-grid) in the same callback

Time:06-01

I am learning R shiny, using AG-GRID javascript component without a wrapper, making the communication possible between frontend and backend, and everything works properly for now.

The frontend sends every change in the editable grid to the backend, that will perform the same transaction on the database, using the

function onCellValueChanged(params) {
Shiny.setInputValue("inputID",params.data, {priority: "event"})
}

However now I am trying to not send ONLY the grid data from the backend to the frontend at the startup, but also a dinamically computed list of values for a column formatted with a dropdown. The code to compute it is not here as it's not really necessary in this example, but very easily I'll just serve at the beginning and at every onCellValueChanged a new list containing only the values not already set (so the user can set them only once per table).

However I can't understand how to serve 2 different files (the grid data that I am already sending and the initial list), instead of one, from the backend using

session$sendCustomMessage("jsondata1",dataJSON1)

and listening them from the backend using

Shiny.addCustomMessageHandler("jsondata1", function(myconstruct))

as it works great for a single json file, but I am failing to apply the same concept for 2 of them.

I tried bundling the requests like

session1-send-griddata
   session2-send-dropdownlist
   end
end

but it was not working and it also felt wrong.

here below a very basic example:

   library(shiny)
    library(RSQLite)
    library(DBI)
    library(tidyverse)
    library(jsonlite)

###################
#### JAVSCRIPT ####
###################

myscript <-'
$(document).ready(function () {

//here I just have 1 input parameter to have it working, but I would need to add a second parameter once I am able to retrieve the values for mycol2
  function gridOptions(rowData) {
    return {
      columnDefs: [
        { field: "COL1" },
        { field: "COL2", 
          cellEditor: "agRichSelectCellEditor", 
          cellEditorPopup: true, 
//this needs to be parametrised
          cellEditorParams: { values: ["Value 1", "Value 2", "Value 3"]} },        
      ],
      defaultColDef: {
        flex: 1,
        editable: true,
      },
      rowData: rowData,
      enableRangeSelection: true,
      enableFillHandle: true,
      undoRedoCellEditing: true,
      undoRedoCellEditingLimit: 5,
      enableCellChangeFlash: true,
      onCellValueChanged: onCellValueChanged,
    };
  }
  
  const gridDiv = document.querySelector("#myGrid");

  Shiny.addCustomMessageHandler("jsondata1", function(rowData) {
//here I just have 1 input parameter to have it working, but I would need to add a second parameter once I am able to retrieve the values for mycol2
     new agGrid.Grid(gridDiv, gridOptions(rowData));
  });
  
});'

myjson <- '[
  {
    "COL1": 1,
    "COL2": "Value 1"
  },
  {
    "COL1": 2,
    "COL2": "Value 2"
  }
]'

###################
#### START DB  ####
###################

con <- dbConnect(RSQLite::SQLite(), ":memory:") 
start <- as.data.frame(fromJSON(myjson)) 
dbWriteTable(con, "requests", start) 
dbReadTable(con, "requests") 

###################
#### START APP ####
###################

ui <- fluidPage(
  tags$head(
    tags$script(src = "https://unpkg.com/ag-grid-enterprise/dist/ag-grid-enterprise.min.js")
  ),   
  tags$script(myscript),
  div(id = "myGrid", style="height: 300px; ", )
)

server <- function(input, output, session) {
  
  data <- dbReadTable(con, "requests")
  dataJSON1<-toJSON(data)

  col2val <- '[{"Value 1", "Value 2", "Value 3"}]'

  # here I am sending the main grid data, but I would also like to send col2val to define the possible values for the dropdown in col2
  session$sendCustomMessage("jsondata1",dataJSON1)
}

shinyApp(ui = ui, server = server)
dbDisconnect(con)

CodePudding user response:

You can use a list.

  session$sendCustomMessage("jsondata1", list(rowData = dataJSON1, x = what_you_want))

  Shiny.addCustomMessageHandler("jsondata1", function(message) {
     // do something with message.x
     new agGrid.Grid(gridDiv, gridOptions(message.rowData));
  });
  • Related