dreamRs / toastui

R htmlwidgets for ToastUI libraries: grid, calendar and chart
https://dreamrs.github.io/toastui
Other
83 stars 8 forks source link

datagrid HTML dependencies issue with insertUI #28

Open DivadNojnarg opened 1 year ago

DivadNojnarg commented 1 year ago

Hi Victor,

When using insertUI within a golem modularised app, I end up with:

Uncaught ReferenceError: datagrid is not defined
    at eval (eval at tryEval (htmlwidgets.js:252:16), <anonymous>:1:1)
    at tryEval (htmlwidgets.js:252:16)
    at window.HTMLWidgets.evaluateStringMember (htmlwidgets.js:799:23)
    at shinyBinding.renderValue (htmlwidgets.js:521:30)
    at e.value (outputBinding.ts:48:12)
    at delegator.<computed> [as onValueChange] (htmlwidgets.js:112:23)
    at e.value (outputAdapter.ts:38:20)
    at e.value (shinyapp.ts:559:17)
    at e.<anonymous> (shinyapp.ts:736:20)
    at e.value (shinyapp.ts:717:29)
    at e.value (shinyapp.ts:700:12)
    at i.onmessage (shinyapp.ts:350:15)

on the JS side. After few investigations, I realised that the JS dependencies for toastui are not available in the HTML inspector source tab, like they traditionally do for other tools: Screenshot 2022-10-21 at 14 53 52.

This is maybe related to how packer handle dependencies by not using htmlDependency. I manually have to do this to get it working, which is not very convenient:

golem_add_external_resources <- function() {
  add_resource_path(
    "www", app_sys("app/www")
  )

  tags$head(
    favicon(),
    bundle_resources(
      path = app_sys("app/www"),
      app_title = "posApp"
    ),
    # for app tour
    use_cicerone(),
    use_waiter(),

    # HERE
    htmltools::findDependencies(datagrid()),

  )
}

which is nearly the same as doing use_waiter above.

I don't know how you want to handle this, create a use_toastui or see with John if this can be changed in packer.

pvictor commented 1 year ago

Hello,

There must be something else here. {packer} doesn't change the way html dependencies are handled for htmlwidgets.

These 3 tests works fine for me (restarting session between testing them) :


library(shiny)
library(toastui)

ui <- fluidPage(
  actionButton("test1", "Test 1"),
  actionButton("test2", "Test 2"),
  actionButton("test3", "Test 3"),
  tags$div(id = "placeholder")
)

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

  observeEvent(input$test1, {
    insertUI(
      selector = "#placeholder",
      ui = tagList(
        datagrid(rolling_stones_50)
      )
    )
  })

  observeEvent(input$test2, {
    insertUI(
      selector = "#placeholder",
      ui = tagList(
        renderDatagrid({
          datagrid(rolling_stones_50)
        })
      )
    )
  })

  observeEvent(input$test3, {
    insertUI(
      selector = "#placeholder",
      ui = tagList(
        datagridOutput("grid")
      )
    )
  })

  output$grid <- renderDatagrid({
    datagrid(rolling_stones_50)
  })

}

shinyApp(ui, server)

Nonetheless I think that's better if dependencies are loaded when app is initialized.

DivadNojnarg commented 1 year ago

Yes also working for me with these examples. It could be a bad JS timing issue on my side, the app being more complex. The only concern about preloading deps even when the widget is not initially here is the app starting time which could be impacted.