Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: add ignoreIdentical param to observeEvent() #1484

Closed
daattali opened this issue Nov 24, 2016 · 6 comments
Closed

Feature request: add ignoreIdentical param to observeEvent() #1484

daattali opened this issue Nov 24, 2016 · 6 comments

Comments

@daattali
Copy link
Contributor

daattali commented Nov 24, 2016

I often use observeEvent(x, ...) when I want to tell shiny that a reactive code block should be executed whenever a specific value x changes. Usually observeEvent() does exactly what I want it to do, but because it gets fired when x gets invalidated, then it can also fire when x hasn't changed at all. I realize this is the correct behaviour based on how reactivity works, but in my opinion it's easier for people to think of it as only firing whenever the value changes rather than gets invalidated. So I was wondering if it'd be possible to add a parameter to observeEvent() that will do that?

Example:

library(shiny)

ui <- fluidPage(
  actionButton("btn", "Button")
)

server <- function(input, output, session) {
  num5 <- reactive({
    input$btn
    5
  })
  observeEvent(num5(), {
    cat("click\n")
  })
}

shinyApp(ui = ui, server = server)

It wouldn't be too far-fetched to think that the observer would only get run when num5() changes. It's wrong, but it can be useful to want to do that.

I realize this may be a strange request that doesn't really fit the reactivity model, and fully accept any incoming judgment if this is a dumb idea

@bborgesr
Copy link
Contributor

Hmm, this seems like a reasonable request IMO. Thoughts, @wch, @jcheng5?

@jcheng5
Copy link
Member

jcheng5 commented Nov 24, 2016

In the past, I've thought of this as a property of the reactive expression (does it invalidate its dependents if its new value is the same as the old?), not the observer. (This is actually how reactive expressions originally worked in Shiny, but I soon concluded that laziness was more frequently beneficial than this "de-dupe" behavior.)

You can achieve this yourself with a higher order reactive.

dedupe <- function(r) {
  makeReactiveBinding("val")
  observe(val <<- r(), priority = 10)
  reactive(val)
}

num5 <- dedupe(reactive({
  input$btn
  5
}))

Seems like we might want to start corralling some of these types of things into a shiny reactive extras package (or contribute to Hadley's shinySignals package)...

@daattali
Copy link
Contributor Author

Your beautifully elegant solutions for these things always amaze me. I agree it'd be nice to have a place that aggregates a lot of these more complex constructs that achieve commonly needed results in shiny. I remember the reactiveTrigger you created for @gaborcsardi was also something I'd love to bookmark. This was sort of the idea behind my repo advanced-shiny...

@alandipert
Copy link
Contributor

alandipert commented Apr 29, 2019

Closing because a workaround was accepted.

@sanjmeh
Copy link

sanjmeh commented Sep 13, 2021

I thought I understood shiny reactive exressions quite well till I saw this Joe Cheng's master piece snippet in response to @daattali 's equally valuable question.

dedupe <- function(r) {
  makeReactiveBinding("val")
  observe(val <<- r(), priority = 10)
  reactive(val)
}

num5 <- dedupe(reactive({
  input$btn
  5
}))

I am not sure how this works. How is the invalidation happening here? How does the assignment operator help?
@daattali : could you please please document this on your excellent advanced shiny website?

@daattali
Copy link
Contributor Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants