I am trying to implement user feedback for an app I'm wokring on using the shinyvalidate package. Some of the feedback I want to communicate to the user is whether a value they have selected is within a specific range or not. The range of interest depends on another input they have made (I have included a simplified repex of the code).
Thus, whether the precondition of interest is met depends on a reactive value. I first define a function that checks whether a provided value is within a specified range. Then I call this function within add_rule() using a reactive as an argument to the function. This results in an error, which states that I cannot access the reactive using add_rule. This is supposedly the case because the InputValidator object is not a reactive consumer.
Error message:
Warning: Error in : Can't access reactive value 'num1' outside of reactive consumer.
i Do you need to wrap inside reactive() or observer()?
55: <Anonymous>
Error : Can't access reactive value 'num1' outside of reactive consumer.
i Do you need to wrap inside reactive() or observer()?
However, if I use an unnamed function within add_rule(), I can specify a range which depends on a reactive and I no longer get the error message. The unnamed and named functions I use are identical and I don't understand why I get error message using a named function but I do not get the error message when using the named function.
Here is my code using the named function:
library(shiny)
library(shinyvalidate)
checkRange <- function(value, value2){
if(value < -2 * value2 || value > 2 * value2 ){
paste0("Please specify a number that is within the range: ", -2 * value2, ":", 2 * value2, " - Tank you!")
}
}
ui <- fluidPage(
fluidRow(
numericInput("num1",
"Please specify your first number",
value = NULL),
numericInput("num2",
"Please specify a different number",
value = NULL),
verbatimTextOutput("selectedNums")
)
)
server <- function(input, output, session){
iv <- InputValidator$new()
iv$add_rule("num1", sv_required())
iv$add_rule("num2", sv_required())
iv$add_rule("num2", checkRange, value2 = input$num1)
iv$enable()
output$selectedNums <- renderPrint({
req(iv$is_valid())
paste0("The first number = ", input$num1, " and the second number = ", input$num2)
})
}
app <- shinyApp(ui, server)
runApp(app)
And here is the code using an anonymous function (UI and server code are largely identical with the exception to one call to iv$add_rule()):
library(shiny)
library(shinyvalidate)
ui <- fluidPage(
fluidRow(
numericInput("num1",
"Please specify your first number",
value = NULL),
numericInput("num2",
"Please specify a different number",
value = NULL),
verbatimTextOutput("selectedNums")
)
)
server <- function(input, output, session){
iv <- InputValidator$new()
iv$add_rule("num1", sv_required())
iv$add_rule("num2", sv_required())
iv$add_rule("num2", function(value){
if(value < - 2 * input$num1 || value > 2 * input$num2){
paste0("Please specify a number that is within the range: ", -2 * input$num1, ":", 2 * input$num1, " - Tank you!")
}
})
iv$enable()
output$selectedNums <- renderPrint({
req(iv$is_valid())
paste0("The first number = ", input$num1, " and the second number = ", input$num2)
})
}
app <- shinyApp(ui, server)
runApp(app)
I would prefer to use the named function since I would like to reuse the code multiple times. Could anyone help me out as to why I get an error message with the named function but not with the unnamed one?