yellowlemon
yellowlemon

Reputation: 43

Triggering alerts with validate-need in Shiny?

I am having difficulty triggering an alert in a Shiny app that I have created. The app itself is very simple, and displays one slider with numbers and a line plot. However, I would like for an alert to be triggered whenever the slider is set to a value above 5. Here is the code:

UI

library(shiny)
library(shinythemes)
library(shinyBS)

shinyUI(fluidPage(theme = shinytheme("superhero"),
              tags$head(
                tags$style(HTML("
  .shiny-output-error-validation {
    color: green;
  }
"))
              ),

sidebarLayout(
sidebarPanel(
  sliderInput("samplestat",
              "Value:",
              min = 1,
              max = 10,
              value = 1)
),

    mainPanel(
  h3("Graph", style = "font-family: 'Jura'; color: blue; font-size: 32px;"),
  HTML("<p>Graph</p>"),
  plotOutput("LinePlot")
)
)
))

SERVER

library(shiny)
library(ggplot2)
library(scales)

samplestat <- function(input) {
if (input > 5) {
"Choose another value. samplestat must be below 5!"
} else if (input < 4) {
FALSE
} else {
NULL
}
}

shinyServer(function(input, output) {

data <- reactive({
validate(
  need(input$data != "", "Please select a value below 5")
)
get(input$data)
})

output$LinePlot <- renderPlot({

n=1:10
samplestat <- seq(min(n), max(n), length.out = input$samplestat)

plot(samplestat, type = "o", col = 'blue', border = 'white', xlab="X Axis", ylab ="Y Axis")
}

)

})

When I run this code, the line and slider displays, but I do not get any alert when I slide the slider to a value above 5. I am not sure if I am possibly using validate-need incorrectly, or whether I have overlooked something else.

Upvotes: 1

Views: 5576

Answers (1)

Weihuang Wong
Weihuang Wong

Reputation: 13128

You should place validate(...) insider renderPlot({...}). That is, your server.R should be something like:

function(input, output) {
  output$LinePlot <- renderPlot({
    validate(
      need(input$samplestat <= 5, "Please select a value below 5")
    )
    n <- 1:10
    samplestat <- seq(min(n), max(n), length.out = input$samplestat)
    plot(samplestat, type = "o", col = 'blue', 
      fg = 'white', xlab= "X Axis", ylab = "Y Axis")
  })
}

which produces this output: enter image description here


Note that there should be no problem with wrapping your validation code in a reactive function. Suppose your function to test for a condition is

validate_samplestat <- function(input) {
  if (input > 5) {
    "Choose another value. samplestat must be below 5!"
  } else {
    NULL
  }
}

You can wrap this in reactive in your main server function, and place the reactive function in your output rendering function. The main thing is to place the bit of code that calls validate in your output rendering function:

function(input, output) {
  v <- reactive({
    validate(validate_samplestat(input$samplestat))
  })

  output$LinePlot <- renderPlot({
    v() # <--- validate here
    n <- 1:10
    samplestat <- seq(min(n), max(n), length.out = input$samplestat)
    plot(samplestat, type = "o", col = 'blue', 
      fg = 'white', xlab= "X Axis", ylab = "Y Axis")
  })
}

Upvotes: 4

Related Questions