Skip to content

[Bug]: bookmark, dataTableProxy, and telemetry incompability in specific user-case #190

@vgilbart

Description

@vgilbart

Guidelines

  • I agree to follow this project's Contributing Guidelines.

Existing Issues

No response

What happened?

Adding shiny.telemetry::use_telemetry() is incompatible with a DT::updateSearch() and enableBookmarking specific user-case. It will remove the datatable searches saved with the bookmarking.

I've managed to overcome this bug by replacing shiny.telemetry::use_telemetry() with tags$script("$(document).on('shiny:sessioninitialized', function(event));").

Steps to reproduce

  1. Load the app

  2. Choose dataset

  3. Choose columns

  4. Do a search in the datatable

  5. Bookmark

  6. Reload the app using the bookmark

  7. Do the same thing but change the app code by removing shiny.telemetry::use_telemetry() and adding tags$script("$(document).on('shiny:sessioninitialized', function(event));"), instead.

Expected behavior

Bookmarked datatable searches should still appear.

Attachments

This example is a bit buggy (you'll get a warning when changing dataset because the column name does not exist) but it represents an example of what I was trying to achieve:

  • choice of a dataset
  • choice of a dataset-specific parameter to output a datatable
  • do a search in the datatable
  • save bookmark
  • re-open the app via the bookmark, the bookmarked search should still appear
library(DT)
library(shiny)
library(shiny.telemetry)

ui <- function(request) {
  fluidPage(
    ###################
    # ISSUE HERE
    ###################
    # This does not work:
    shiny.telemetry::use_telemetry(),
    # This works:
    # tags$script(
    #   "$(document).on('shiny:sessioninitialized', function(event));"
    # ),
    
    selectInput("comparison", "Select a table:", choices = c("iris", "iris2")),
    selectInput(
      "column",
      "Select a col:",
      choices = NULL,
      multiple = TRUE
    ),
    
    DT::dataTableOutput('tbl')
    ,
    bookmarkButton(label = "Bookmark", title = "Link to this view")
    
  )
}

telemetry <- Telemetry$new(app_name = "myApp",
                           data_storage = DataStorageLogFile$new(file.path("telemetry.txt")))


server = function(input, output, session) {
  telemetry$start_session(track_values = TRUE,
                          track_inputs = FALSE)
  full_tbl <- reactive({
    req(input$comparison)
    if (input$comparison == "iris") {
      data <- iris
    } else {
      data <- iris
      colnames(data) <- paste0(colnames(data), '2')
    }
    data
  })
  
  column_choices <- reactive({
    colnames(full_tbl())
  })
  
  observeEvent(c(input$comparison), {
    # Don't update column if we have just restored
    if (!isRestored()) {
      updateSelectInput(session,
                        inputId = "column",
                        choices = column_choices())
    }
    isRestored(F)
  })
  
  isRestored <- reactiveVal(F)
  
  onRestore(function(state) {
    # Select choice from what has been bookmarked
    updateSelectInput(
      session,
      inputId = "column",
      selected = state$input$column,
      choices = column_choices()
    )
    isRestored(T)
  })
  
  # exclude some values query variables from url
  setBookmarkExclude(
    names = c(
      "tbl_rows_all",
      "tbl_rows_selected",
      "tbl_columns_selected",
      "tbl_cells_selected",
      "tbl_rows_current",
      "tbl_state",
      "tbl_cell_clicked"
    )
  )
  
  # create filtered
  tbl <- reactive({
    req(input$column)
    full_tbl()[, input$column, drop = F]
  })
  
  # proxy for table manipulations
  tbl_proxy <- dataTableProxy("tbl")
  
  # restore table selection and search
  onRestored(function(state) {
    DT::updateSearch(tbl_proxy,
                     keywords = list(global = state$input$tbl_search))
  })
  
  output$tbl <-  DT::renderDT({
    tbl()
  })
}

shinyApp(ui, server, enableBookmarking = "url")

Screenshots or Videos

With tags$script("$(document).on('shiny:sessioninitialized', function(event));"), it works:

this_works

With shiny.telemetry::use_telemetry(), it does not work:

this_does_not_work

The example bookmark search is: ?_inputs_&comparison="iris2"&column=["Sepal.Width2"%2C"Petal.Length2"%2C"Petal.Width2"]&tbl_search="3.3"

Additional Information

I might be wrong but I believe the issue is that tbl() is being updated once too much. It made me think that it might be an issue with my reactive blocks, but since I've managed to make it work by modifying the output of shiny.telemetry::use_telemetry() I am not so sure.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions