Using message inside of reactives

*Apologies if there anything incorrect about my post, title, or formatting as this is my first post on this forum.

I'm currently working my way through Mastering Shiny and had a question relating to an example in chapter 6.2.4 on debugging reactive code.

In this section, Hadley provides the following demonstration app:

library(shiny)

ui <- fluidPage(
  sliderInput("x", "x", value = 1, min = 0, max = 10),
  sliderInput("y", "y", value = 2, min = 0, max = 10),
  sliderInput("z", "z", value = 3, min = 0, max = 10),
  textOutput("total")
)
server <- function(input, output, session) {
  observeEvent(input$x, {
    updateSliderInput(session, "y", value = input$x * 2)
    message(glue("Updating y from {input$y} to {input$x * 2}"))
  })
  
  total <- reactive({
    total <- input$x + input$y + input$z
    message(glue("New total is {total}"))
    total
  })
  
  output$total <- renderText({
    total()
  })
}

shinyApp(ui, server)

I'm noticing some weird behavior in the messages printed out to my console when moving the x slider between 0 and 5. Doing this results in two messages being printed to my console, of which only the second value is correct. For example, the image below shows the error message that results from moving x from 3 to 4:

Capture

However, when an x > 5 is selected, the problem goes away and only one new total is returned. Can anyone explain to me why this is happening?

Thanks!

reactives typically only get called and/or updated when they are needed by an output. In a sense, the calls get executed in reverse.

The way this app is written, I would expect a change in x to invalidate output$total. This would invalidate total(), which would recalculate based on x, y, and z.

It looks like that invalidation and calculation of total() is happening before the observeEvent for input$x gets triggered. Once that event is triggered, tough, y is updated, causing output$total and total() to invalidate again, causing the second update to total().

Based on the way we humans think, we expect to see a change in x cause a change in y and then a change in total(). That just isn't quite the way that shiny operates.

Someone please correct me if I'm off track. The order in which shiny does things isn't always intuitive to me.

This topic was automatically closed 54 days after the last reply. New replies are no longer allowed.