Module of Shiny app needed to enable functionality to
setting breakpoint. Must be used in the server
part of
Shiny app or in the function which is then used in the
server
part of app.
Arguments
- keyEvent
key to run modal dialog with the functionality to set breakpoint.
"F4"
by default.- id
namespace used for all inputs and outputs in this module.
"shinybreakpoint"
by default. Change if in the app some other module is used which already has"shinybreakpoint"
namespace.- varName
setting breakpoint is not equal to inserting only
browser()
, but also additional code, one of which is assignment operation. This parameter determines the variable name to assign value."....envirr"
by default. Change if this name is already in use somewhere in the app.
Value
Used for side effect - adds modal dialog to the Shiny app
with the options to set breakpoint. Modal dialog is shown
when the key specified in keyEvent
is pressed.
App structure
One of the core concepts which founds this module is the
necessity to re-run the objects present in the server
part of app. This is possible only when these objects
do not live directly in the server
, but in the function
which is then used in server
. This naturally harmonizes
with the modules, but it needs the separate function for
objects which would be used directly in the server
.
shinybreakpointServer
module was developed having Bootstrap 5
in mind, that's why it is recommended to use bslib::bs_theme()
to set up Bootstrap 5. Otherwise the UI experience will be
worse.
Possibility to filter reactive context depending on specific
input
or output
needs shiny::reactlog()
enabled,
which is done by set_filtering_by_id()
. This line
of code needs to be removed before app will be sent to production
(which is of course true also for
shinybreakpoint::shinybreakpointServer()
line).
See example section below for the idea of how to include all of this
requirements in the app. This can also be done by
snippet()
for new apps.
Filtering by Id
Filtering by Id is very experimental and may fail in not yet fully understandable way.
As long as shiny::reactlog()
is enabled (by function
set_filtering_by_id()
, because this function
is responsible also to manage some needed files in temporary directory, i.e.
it won't be enough to just use options(shiny.reactlog = TRUE)
or similar),
it is possible to filter displayed source code based on input
or output
Id, i.e. only the relevant source code
(reactive
s, observe
s and render*
functions)
will be shown. Two modes are available:
Last changed input - last changed input is tracked automatically, i.e. nothing special needs to be done.
Chosen Id - by holding
Ctrl
on PC orCmd
on Mac and hovering mouse overinput
oroutput
, Id for this element will be saved (which will be indicated by displaying cursor of type 'progress' for a moment).
To successfully see all relevant source code for Id, it is necessary
to ensure that code inside reactive
s, observe
s and render*
functions
is in curly ({}
) brackets and that observe
s as well as shiny::bindEvent()
(if used) have label, i.e. string is passed directly to the label
parameter. Label needs to be unique across all labels and Ids. Additionally,
if shiny::bindEvent()
is used on render*
function, label must be the same as
the output
Id. Because in this last case Id is masked by shiny::bindEvent()
,
there is no afraid that label and Id won't be unique.
Q
option (exit) can't be use in debug mode to properly use filtering by Id
. Please
use c
or f
to close the debug mode - this will return to the app and
then app can be stopped in usual way if needed.
Examples
# To run example, copy-paste to file, save
# the file and run the app. Then press "F4"
# to open the modal dialog.
if (FALSE) {
library(shiny)
shinybreakpoint::set_filtering_by_id() # TODO: remove
appServer <- function(input, output, session) {
observe({
input$num
}, label = "observe_print_num_input")
}
shinyApp(
ui = fluidPage(
theme = bslib::bs_theme(5),
numericInput("num", "Num", 0)
),
server = function(input, output, session) {
shinybreakpoint::shinybreakpointServer() # TODO: remove
appServer(input, output, session)
}
)
}