Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #40: SharedData across shiny modules #114

Merged
merged 4 commits into from
Nov 17, 2021
Merged

Fix #40: SharedData across shiny modules #114

merged 4 commits into from
Nov 17, 2021

Conversation

jcheng5
Copy link
Member

@jcheng5 jcheng5 commented Nov 9, 2021

The bug: SharedData objects constructed inside Shiny modules, were not returning any values for sd$selection() and other reactive methods. This is because the id sent to the client and the id used by the server weren't the same--the server version had the module's namespace automatically prefixed. With this fix, the server uses the same id as the client.

Implementation notes

SharedData group should transcend modules (it's a global
namespace). This isn't as crazy as it sounds, because
the default group value is a random ID.

SharedData$new(..., group = session$ns("groupname")) can
be used to opt into namespaces if that's desired.

Note that this change doesn't break a scenario that works
today; before this commit, the reactive accessors on
SharedData that originated in modules, simply did not work.

Testing notes

Run the following app. Select some points on the plot. Without the fix, the reported number of selected points is 0; with the fix, a correct number is reported. (Note that it might sometimes seem like the reported number is a little too high--this is because of overplotted points, and is almost certainly actually the correct number.)

library(shiny)
library(crosstalk)
library(plotly)

modUI <- function(id) {
  ns <- NS(id)
  tagList(
    p(
      "Number of points selected:",
      textOutput(ns("count"), container = strong)
    ),
    plotlyOutput(ns("plotly1"))
  )
}

mod <- function(id) {
  moduleServer(id, function(input, output, session) {
    sd <- SharedData$new(cars, group = "a")
    output$plotly1 <- renderPlotly({
      plot_ly(sd, type = "scatter", mode = "markers", x = ~ speed, y = ~ dist) %>%
        highlight("plotly_selected")
    })
    output$count <- renderText({
      sum(sd$selection())
    })
  })
}


ui <- basicPage(
  p(
    strong("Instructions:"),
    "Select some points in the plot, and make sure ",
    "'Number of points selected:' shows the correct value."
  ),
  hr(),
  modUI("one")
)

server <- function(input, output, session) {
  mod("one")
}

shinyApp(ui, server)

@jcheng5
Copy link
Member Author

jcheng5 commented Nov 9, 2021

Fixes #40

expect_identical(shiny::isolate(sd1$selection()), res)
expect_identical(shiny::isolate(sd2$selection()), res)

sess$setInputs(".clientValue-foo-selection" = c("149", "150"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
sess$setInputs(".clientValue-foo-selection" = c("149", "150"))
sess$setInputs(".clientValue-foo-selection" = as.character(c(nrow(iris) - 1, nrow(iris))))

Copy link
Contributor

@cpsievert cpsievert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also add a news item, thanks!

SharedData group should transcend modules (it's a global
namespace). This isn't as crazy as it sounds, because
the default group value is a random ID.

`SharedData$new(..., group = session$ns("groupname"))` can
be used to opt into namespaces if that's desired.

Note that this change doesn't break a scenario that works
today; before this commit, the reactive accessors on
SharedData that originated in modules, simply did not work.
@jcheng5 jcheng5 merged commit ff484f7 into main Nov 17, 2021
@jcheng5 jcheng5 deleted the joe/bugfix/modules branch November 17, 2021 20:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants