简体   繁体   中英

r shiny Prevent an app from crashing when numericInput is empty

I have a very simple Shiny app that is working. The user enters a value on box 1 and then in box 2 and then hits 'run'.

However, when the user hits backspace in one of the two numericInput cells until nothing is entered, the app crashes.

How could I prevent it from crashing? Thank you very much!

library(shiny)
library(shinyjs)

ui <- fluidPage(
  useShinyjs(),
  actionButton("run", label = "Run calculations!"),
  # Input 1
  numericInput("inNumber1", label = "Input number 1", 
               value = 100, min = 10, max = 200, step = 10),
  # Message that shows up if the value of inNumber1 is outside the allowed range:
  hidden(h5("Enter a value between 10 and 200!",
            id = "message1",
            style = "font-weight:bold;color:orange;")),

  uiOutput("inNumber2"),
  # Message that shows up if the value of inNumber1 is outside the allowed range:
  hidden(h5("Enter a value between 10 and the value of Input number 1!",
            id = "message2",
            style = "font-weight:bold;color:orange;")),

  textOutput("out1"),
  textOutput("out2")
)

server <- function(input, output, session) {

  # Input 2 - dependent on Input 1
  observeEvent(input$inNumber1, {

    # Is input$inNumber1 outside the allowed range?
    if (input$inNumber1 < 10 | input$inNumber1 > 200) {
      shinyjs::show("message1")
    } else {
      shinyjs::hide("message1")
    }
    output$inNumber2 <- renderUI({
      if (is.null(input$inNumber1)) return(NULL)
      numericInput("inNumber2", label = "Input number 2", 
                   value = 100, min = 10, max = input$inNumber1, step = 10)
    })
  })

  observeEvent(input$inNumber2, {

    # Is input$inNumber2 outside the allowed range?
    if (input$inNumber2 < 10 | input$inNumber2 > input$inNumber1) {
      shinyjs::show("message2")
    } else {
      shinyjs::hide("message2")
    }

  })

  observeEvent(input$run, {

    # Check Input 1:
    number1 <- input$inNumber1
    if (number1 < 10 | number1 > 200) {
      warning1 <- "Input 1 must be between 10 and 200"
    } else {warning1 <- renderText({NULL})}

    output$out1 <- renderText({number1})

    number2 <- input$inNumber2  # value 2
    maxnumber2 <- input$inNumber1
    if (number2 > maxnumber2) {
      # warning(paste0("number2 must be lower than ", maxnumber2))
      number2 <- maxnumber2
    }
    output$out2 <- renderText({number2})


  })
}

shinyApp(ui, server)

Thank you very much!

Sorry, that was a little flip and rushed. Have a look at the following code, I think it works fine now.

library(shiny)
library(shinyjs)

ui <- fluidPage(
  useShinyjs(),
  actionButton("run", label = "Run calculations!"),
  # Input 1
  numericInput("inNumber1", label = "Input number 1", 
               value = 100, min = 10, max = 200, step = 10),
  # Message that shows up if the value of inNumber1 is outside the allowed range:
  hidden(h5("Enter a value between 10 and 200!",
            id = "message1",
            style = "font-weight:bold;color:orange;")),

  uiOutput("inNumber2"),
  # Message that shows up if the value of inNumber1 is outside the allowed range:
  hidden(h5("Enter a value between 10 and the value of Input number 1!",
            id = "message2",
            style = "font-weight:bold;color:orange;")),

  textOutput("out1"),
  textOutput("out2")
)

server <- function(input, output, session) {

  # Input 2 - dependent on Input 1
  observeEvent(input$inNumber1, {

    req(input$inNumber1)

    # Is input$inNumber1 outside the allowed range?
    if (input$inNumber1 < 10 | input$inNumber1 > 200) {
      shinyjs::show("message1")
    } else {
      shinyjs::hide("message1")
    }
    output$inNumber2 <- renderUI({
      if (is.null(input$inNumber1)) return(NULL)
      numericInput("inNumber2", label = "Input number 2", 
                   value = 100, min = 10, max = input$inNumber1, step = 10)
    })
  })

  observeEvent(input$inNumber2, {

    req(input$inNumber1, input$inNumber2)

    # Is input$inNumber2 outside the allowed range?
    if (input$inNumber2 < 10 | input$inNumber2 > input$inNumber1) {
      shinyjs::show("message2")
    } else {
      shinyjs::hide("message2")
    }

  })

  observeEvent(input$run, {

    req(input$inNumber1, input$inNumber2)

    # Check Input 1:
    number1 <- input$inNumber1
    if (number1 < 10 | number1 > 200) {
      warning1 <- "Input 1 must be between 10 and 200"
    } else {warning1 <- renderText({NULL})}

    output$out1 <- renderText({number1})

    number2 <- input$inNumber2  # value 2
    maxnumber2 <- input$inNumber1
    if (number2 > maxnumber2) {
      # warning(paste0("number2 must be lower than ", maxnumber2))
      number2 <- maxnumber2
    }
    output$out2 <- renderText({number2})


  })
}

shinyApp(ui, server)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM