observeEvent in Shiny using functions

Is there a way to update many items in an observeEvent through a function?

For example, I want to update the radio buttons in the observeEvent below ...

library(shinydashboard)
library(shiny)

ui <- dashboardPage(
  dashboardHeader(title = "test"),
  dashboardSidebar(
    radioButtons("species1", 
                 label = "species1", 
                 choices = unique(iris$Species),
                 selected = "setosa"),
    radioButtons("species2", 
                 label = "species2", 
                 choices = unique(iris$Species),
                 selected = "setosa"),
    radioButtons("species3", 
                 label = "species3", 
                 choices = unique(iris$Species),
                 selected = "setosa")
  ),
  dashboardBody(
    "Not relevant"
  )
)

server <- function(input, output, session) {
  
  # I want these observe events in a function or done better
  observeEvent(input$species1,{

    updateRadioButtons(session,
                       "species2",
                       selected = input$species1)

    updateRadioButtons(session,
                       "species3",
                       selected = input$species1)
  })

  observeEvent(input$species2,{

    updateRadioButtons(session,
                       "species1",
                       selected = input$species2)

    updateRadioButtons(session,
                       "species3",
                       selected = input$species2)
  })

  observeEvent(input$species3,{

    updateRadioButtons(session,
                       "species1",
                       selected = input$species3)

    updateRadioButtons(session,
                       "species2",
                       selected = input$species3)
  })
}
shinyApp(ui, server)

but with a function. So the server side would look like this (though this doesn't work).

server <- function(input, output, session) {
  
  # this does not work
  species_observer <- function(species_input, species_text, session){
    
    species_vec <- c("species1", "species2", "species3")
    
    species_vec_unmatched <- species_vec[species_vec != species_text]
    
    observeEvent(species_input,{
      
      updateRadioButtons(session,
                         species_vec_unmatched[1],
                         selected = species_input)
      
      updateRadioButtons(session,
                         species_vec_unmatched[2],
                         selected = species_input)
      
    })
  }
  
  species_observer(input$species1, "species1", session)
  species_observer(input$species2, "species2", session)
  species_observer(input$species3, "species3", session)
  
}

Heres a solution based on a meta-programming concept.


library(glue)
library(rlang)
server <- function(input, output, session) {
    species_observer <- function(source){
    others <- setdiff(c('species1','species2','species3'),source)
    glue("    
 observeEvent(input${source},{{
    updateRadioButtons(session,
                      '{others[1]}',
                       selected = input${source})
    updateRadioButtons(session,
                       '{others[2]}',
                       selected = input${source})
  }})")
  }

  walk(paste0("species",1:3),
       ~eval(parse_expr(species_observer(.x))))
  
}
1 Like

Excellent. Thanks for that.

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

If you have a query related to it or one of the replies, start a new topic and refer back with a link.