Observer evaluation too eager?

130 views
Skip to first unread message

Norman Packard

unread,
Aug 19, 2014, 6:30:36 PM8/19/14
to shiny-...@googlegroups.com

Hi!

I am misunderstanding something about observe().

In the example below, I am expecting the contents of observe() to be executed only when (and immediately when) input$bar changes, i.e., when the actionButton is pushed.

Instead, the contents are executed immediately.  In the warning message (seen in the log file), I see that input$bar=0, its initial value. 

Shouldn't observe() wait to get executed until the button is pushed??

shinyUI(
    pageWithSidebar(
        headerPanel('Foo'),
        sidebarPanel(
            actionButton('bar',"Bar")
            ),
        mainPanel(            )
        )
    )

shinyServer(function(input, output,session) {
    observe({
        input$bar
        warning(paste('input$bar value = ',input$bar))
        warning("shouldn't get here without pushing 'bar' button")
    })
})

Sigbert Klinke

unread,
Aug 26, 2014, 11:26:59 AM8/26/14
to shiny-...@googlegroups.com
I guess that shiny must run once through the anonymous server function at the beginning. In observe could be something that is necessary to generate some initial output.

David Wahman

unread,
Aug 26, 2014, 2:10:02 PM8/26/14
to shiny-...@googlegroups.com
I believe the following code gets you the desired result.  This forces the update to wait until the button has been pushed at least once to move it from 0 to 1.

shinyServer(function(input, output, session) {
  observe({
    if(input$bar == 0) return(NULL)
    warning(paste('input$bar value = ',input$bar))
    warning("shouldn't get here without pushing 'bar' button")
  })
})

Norman Packard

unread,
Aug 27, 2014, 10:16:30 PM8/27/14
to shiny-...@googlegroups.com
Sigbert, David,

Thanks very much for your replies.  Sigbert, I guess you are right, but this behavior seems to introduce an unintended behavior.  I guess I was hoping to hear from a developer why it might make sense.  David, your work-around is very clean, and I will use it.

Joe Cheng

unread,
Aug 28, 2014, 9:16:41 PM8/28/14
to Norman Packard, shiny-...@googlegroups.com
This is the intended behavior and David's suggestion is the idiom we recommend. Observers (and reactive expressions for that matter) can't know what their dependencies are without running.

I understand that this isn't the most intuitive behavior if you're expecting an observer to work like an "event handler" in most other languages or UI frameworks; we have a pull request that's been open forever that adds a facade over observer() to provide an API that's more event handler-like.

This is the basic idiom for event handlers in Shiny:

observe({
  if (input$button == 0) return()  # or however else you detect the starting state

  isolate({
    # Your event handling logic here
  })
})



On Wed, Aug 27, 2014 at 7:16 PM, Norman Packard <nhpa...@gmail.com> wrote:
Sigbert, David,

Thanks very much for your replies.  Sigbert, I guess you are right, but this behavior seems to introduce an unintended behavior.  I guess I was hoping to hear from a developer why it might make sense.  David, your work-around is very clean, and I will use it.

--
You received this message because you are subscribed to the Google Groups "Shiny - Web Framework for R" group.
To unsubscribe from this group and stop receiving emails from it, send an email to shiny-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/shiny-discuss/0bb34326-9e29-43a4-a990-8159a49b8d34%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Norman Packard

unread,
Sep 2, 2014, 7:55:41 PM9/2/14
to shiny-...@googlegroups.com, nhpa...@gmail.com


On Thursday, August 28, 2014 6:16:41 PM UTC-7, Joe Cheng [RStudio] wrote:
This is the intended behavior and David's suggestion is the idiom we recommend. Observers (and reactive expressions for that matter) can't know what their dependencies are without running.

I understand that this isn't the most intuitive behavior if you're expecting an observer to work like an "event handler" in most other languages or UI frameworks; we have a pull request that's been open forever that adds a facade over observer() to provide an API that's more event handler-like.

This is the basic idiom for event handlers in Shiny:

observe({
  if (input$button == 0) return()  # or however else you detect the starting state

  isolate({
    # Your event handling logic here
  })
})


Joe,
Thanks very much for your elucidation.
 
 
Reply all
Reply to author
Forward
0 new messages