using purrr::walk to instate multiple event observers

  • A+
Category:Languages

I have a group of variables that are used as id's on html elements with matching functions (conveniently named varname.helper()) that I would like to be called whenever an event is triggered on the respective html element.

I tried the following:

server <- function(input, output, session) {     observables <- c("foo1", "foo2", "foo3") # they are obviously much more than 3 vars...     observables %>% walk(function(x) {         observeEvent(quo(!!sym(paste0("input$", x))), quo(!!sym(paste0(x, ".helper"))(input)), handler.quoted=TRUE) } 

But it didn't work. Any ideas?


Your problem starts here. Tidy evaluation is not the optimal way to solve this.

    observeEvent(quo(!!sym(paste0("input$", x))),            quo(!!sym(paste0(x, ".helper"))(input)), handler.quoted=TRUE) 

You want (right?) to get input$foo1 and foo1.helper. With your code, the end result is this cluster of quos, syms and exclamation marks.

First of all, if all your helper variables are doing the same thing, why do you create lots of separate variables called foo1.helper? It would make more sense to put them in a list, so you can use any kind of looping/mapping to make life easier for you:

helpers <- list(foo1 = whatever..., foo2 = whatever...) 

Next,

quo(!!sym(paste0("input$", x))) 

gives you a rather complex object with a specific use case. Rather than using $, you better use the double bracket selection:

input[[x]] 

This lets you select an item from a list based on its name, using a character variable x. These are easier to work with. The $ syntax is just sugar and doesn't let you use character values easily.

To sum up:

observeEvent(input[[x]], quote(helpers[[x]](input)), handler.quoted = TRUE) 

Here's a short example on how to fit these things in your code. Note that you have to use purrr::walk here, as you can't use a for loop. A for loop doesn't work well together with the specific way observers etc are registered by the internals of shiny.

So your code would become:

library(shiny) library(purrr)  ui <- fluidPage(    sidebarLayout(       sidebarPanel(          actionButton("foo1", "Foo 1"),          actionButton("foo2", "Foo 2")       ),       "Nothing here"    ) )  server <- function(input, output) {   helpers <- list(foo1 = quote(cat("foo 1; ")), foo2 = quote(cat("foo 2; ")))   purrr::walk(c("foo1", "foo2"), ~ observeEvent(input[[.x]],          helpers[[.x]], handler.quoted = TRUE)) }  shinyApp(ui = ui, server = server) 

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: