Skip to content

bug with reactive data in dq_render_handsontable #21

@FrankSchiro

Description

@FrankSchiro

When running dq_render_handsontable with a reactive input that changes the number of columns, I get an error when I add too many columns.

In the reproducible example below, you can add columns with the drop down bar. When I add columns with the app, I get this error: Warning: Error in [[: subscript out of bounds

library("rlist")
library(shinyWidgets)
library(shiny)
library(dqshiny)

shinyApp(
    ui = fluidPage(
        dq_handsontable_output("randomTable"),
        pickerInput(
            inputId = "extraCols", 
            label = "Add Columns", 
            choices = c(1, 5:10),
            selected = 0,
            multiple = FALSE
        )
    ),
    server = function(input, output, session) {
        colParams__ <- reactive({
            colParams_ = list()
            for(i in 1:ncol(df0())){
                colParams_ = list.append(colParams_,
                    list(
                        col = names(df0())[i], 
                        type = "dropdown", source = unique(df0()[, i])
                    )
                )
            }
            colParams_
        })
        df0 <- reactive({
            hw <- c("Hello", "my", "funny", "world!")
            df <- data.frame(A = rep(hw, 8), B = hw[c(2,3,4,1)],
            C = 1:8, D = 1:8, stringsAsFactors = FALSE)
            df$D = as.character(df$D)
            n <- as.numeric(input$extraCols)
            print(n)
            for(i in 1:n){
                df <- cbind(df, df[, 1])
            }
            names(df) = letters[1:ncol(df)]
            df
        })
        observeEvent(colParams__(), {
            dq_render_handsontable(
                "randomTable", 
                df0,
                filters = "T",
                page_size = NULL,
                width_align = TRUE,
                col_param = colParams__(),
                horizontal_scroll = TRUE
            )}
        )
    }
)

I noticed this problem is coming from the dq_render_handsontable function.

Below is a small segment of code from the dq_render_handsontable function. This part of the function is producing the error because it is running update_filters() without first adding filters for the new columns. I modified the code to add new filters to the list like so : filters <<- correct_filters(filters, shiny::isolate(dqv$full[, columns, drop = FALSE]))

This modification makes the app work.

else if (shiny::is.reactive(table_data)) {
          shiny::observeEvent(table_data(), {
              if (no_update) {
                  no_update <<- FALSE
              }
              else {
                  dqv$full <- as.data.frame(table_data())
                  # ----- I added the following 2 lines:
                  filters <<- correct_filters(filters, shiny::isolate(dqv$full[, 
                              columns, drop = FALSE]))
                  # ----- end of addition
                  if (!is.null(filters)) {
                    update_filters(dqv$full[, columns, drop = FALSE], 
                      filters, session)
                  }
              }
          }, ignoreInit = TRUE)
          dqv$full <- as.data.frame(shiny::isolate(table_data()))
      }

One issue with this mod is that it seems to make shiny::observeEvent(app_input[[id]], ...) run more frequently than it should.

I noticed that this observeEvent actually runs 2 + 2 * n times each time I update a cell in the table, where n is the number of times I update columns.

For example, if I add a column once (n=1), then try to edit a cell in the table, observeEvent(app_input[[id]], ...) will run twice and update dqv$full twice. Then it will run the observeEvent two more times, but the second two times nothing gets updated.

If I add another column so that (n=2), 2 + 2 * 2 = 4, so there will be 2 dqv$full update events (where the same data gets update twice. Then there will be 2 more observeEvents where dqv$full does not update. I assume !is.null(app_input[[id]]$changes$source is maybe NULL.

Do you know why this observeEvent runs more when I add more columns ? Also, do you think the way I fixed this bug is okay, or would you recommend something else?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions