diff --git a/DESCRIPTION b/DESCRIPTION index 2ac6300cdb..318fd9d49b 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -78,7 +78,7 @@ Suggests: rsvg, ggridges LazyData: true -RoxygenNote: 7.3.1 +RoxygenNote: 7.3.2 Encoding: UTF-8 Roxygen: list(markdown = TRUE) Config/Needs/check: diff --git a/NEWS.md b/NEWS.md index 27e654f097..948468f958 100644 --- a/NEWS.md +++ b/NEWS.md @@ -4,6 +4,8 @@ * `ggplotly()` now supports the `{ggridges}` package. (#2314) +* `event_data()` has a new `suppress_unregistered_warning` parameter. The relevant warning message has also been updated to reflect that it is often spurious in apps with conditionally-rendered plots (e.g. dashboard apps with multiple tabs). (#1528, #1538) + ## Improvements * `ggplotly()` now works better with the development version of ggplot2 (> v3.4.4). (#2315, #2368) diff --git a/R/shiny.R b/R/shiny.R index a25b653aac..9ce5775f65 100644 --- a/R/shiny.R +++ b/R/shiny.R @@ -113,6 +113,10 @@ register_plot_events <- function(p) { #' If equal to `"event"`, then [event_data()] always triggers re-execution, #' instead of re-executing only when the relevant shiny input value changes #' (the default). +#' @param suppress_unregistered_warning If TRUE, do not throw a warning when +#' this function is called before a plot renders and registers event handlers. +#' (These warnings often occur spuriously in multi-tab apps, where not all plots +#' are immediately rendered.) #' @export #' @seealso [event_register], [event_unregister] #' @references @@ -133,7 +137,8 @@ event_data <- function( ), source = "A", session = shiny::getDefaultReactiveDomain(), - priority = c("input", "event") + priority = c("input", "event"), + suppress_unregistered_warning = FALSE ) { if (is.null(session)) { stop("No reactive domain detected. This function can only be called \n", @@ -143,25 +148,30 @@ event_data <- function( event <- match.arg(event) eventID <- paste(event, source, sep = "-") - # It's possible for event_data() to execute before any - # relevant input values have been registered (i.e, before - # relevant plotly graphs have been executed). Therefore, - # we delay checking that a relevant input value has been - # registered until shiny flushes - session$onFlushed( - function() { - eventIDRegistered <- eventID %in% session$userData$plotlyShinyEventIDs - if (!eventIDRegistered) { - warning( - "The '", event, "' event tied a source ID of '", source, "' ", - "is not registered. In order to obtain this event data, ", - "please add `event_register(p, '", event, "')` to the plot (`p`) ", - "that you wish to obtain event data from.", - call. = FALSE - ) + if (!suppress_unregistered_warning) { + # It's possible for event_data() to execute before any + # relevant input values have been registered (i.e, before + # relevant plotly graphs have been executed). Therefore, + # we delay checking that a relevant input value has been + # registered until shiny flushes + session$onFlushed( + function() { + eventIDRegistered <- eventID %in% session$userData$plotlyShinyEventIDs + if (!eventIDRegistered) { + warning( + "The '", event, "' event tied a source ID of '", source, "' ", + "is not registered. In order to obtain this event data, ", + "please add `event_register(p, '", event, "')` to the plot (`p`) ", + "that you wish to obtain event data from, or set ", + "`suppress_unregistered_warning = TRUE` to suppress this warning ", + "if the plot will eventually register this event, but only ", + "renders conditionally.", + call. = FALSE + ) + } } - } - ) + ) + } # legend clicking returns trace(s), which shouldn't be simplified... parseJSON <- if (event %in% c("plotly_legendclick", "plotly_legenddoubleclick")) { diff --git a/man/event_data.Rd b/man/event_data.Rd index 91a81f9c46..8fdf247b9a 100644 --- a/man/event_data.Rd +++ b/man/event_data.Rd @@ -12,7 +12,8 @@ event_data( "plotly_sunburstclick"), source = "A", session = shiny::getDefaultReactiveDomain(), - priority = c("input", "event") + priority = c("input", "event"), + suppress_unregistered_warning = FALSE ) } \arguments{ @@ -29,6 +30,11 @@ events emitted from that specific plot.} If equal to \code{"event"}, then \code{\link[=event_data]{event_data()}} always triggers re-execution, instead of re-executing only when the relevant shiny input value changes (the default).} + +\item{suppress_unregistered_warning}{If TRUE, do not throw a warning when +this function is called before a plot renders and registers event handlers. +(These warnings often occur spuriously in multi-tab apps, where not all plots +are immediately rendered.)} } \description{ This function must be called within a reactive shiny context.