Why does the displayed shinyFeedback error message in this shiny app sometimes not change?

Viewed 124

I created the shiny app below:

library(shiny)
library(shinyFeedback)
library(tidyverse)

ui <- fluidPage(
  useShinyFeedback(),
  textInput("lst", "Enter numbers in a comma-delimited list"),
  textOutput("lst")
)

server <- function(input, output, session) {
  lst <- reactive({
    bad_vals <- input$lst %>%
      str_split(",") %>%
      unlist() %>%
      keep(~ .x %>% as.numeric() %>% is.na()) %>%
      suppressWarnings()
    err_msg <- str_interp(
      "These aren't numbers: ${str_c(bad_vals, collapse = ', ')}"
    )
    print(err_msg)
    feedbackDanger("lst", !is_empty(bad_vals), err_msg)
    req(is_empty(bad_vals))
    input$lst
  })
  
  output$lst <- renderText(lst())
}

shinyApp(ui, server)

If the user enters a comma-delimited list of numbers, then the app should display the list. If one or more entries in the list is not a number, then the app should display an error message that shows the entries that aren't numbers.

Here's what I see when I quickly enter "1, 2, 3":

enter image description here

If I quickly append ", a, b, c", then I see this:

enter image description here

If I pause and then append ", d", the error message doesn't update:

enter image description here

If I delete the contents of the box and enter "1, 2, 3", I again see what's in the first screenshot. If I then quickly append ", a, b, c, d", I see what I expect to:

enter image description here

Strangely, the error messages printed in the console are correct:

enter image description here

Why isn't the error message in the app updating every time it should?

1 Answers

This is the way how shinyFeedback is implemented. It shows the feedback only if there wasn't any feedback before. Thus, showing a feedback message on top of an existing feedback message won't work.

Thus, you should hide the feedback first (which also resets the feedback message).

Here's a full example (N.B. I refactored your code a bit to avoid duplicate ids)

library(shiny)
library(shinyFeedback)
library(tidyverse)

ui <- fluidPage(
   useShinyFeedback(),
   textInput("lst", "Enter numbers in a comma-delimited list"),
   textOutput("lst_out")
)

server <- function(input, output, session) {
   lst <- reactive({
      bad_vals <- input$lst %>%
         str_split(",") %>%
         unlist() %>%
         keep(~ .x %>% as.numeric() %>% is.na()) %>%
         suppressWarnings()
      err_msg <- str_interp(
         "These aren't numbers: ${str_c(bad_vals, collapse = ', ')}"
      )
      list(input = input$lst,
           is_error = !is_empty(bad_vals),
           error_msg = err_msg)
   })
   
   observeEvent(lst(), {
      hideFeedback("lst")
      feedbackDanger("lst", lst()$is_error, lst()$error_msg)
   })
   
   output$lst_out <- renderText({
      ret <- lst()
      req(!ret$is_error)
      ret$input
   })
}

shinyApp(ui, server)
Related