Dynamically create and manage observeEvents (annotation app)

Hello everyone, this is my first post on this forum :slight_smile:

I am having a problem with designing a shiny application - in summary, I would like my app to be a annotation tool - it downloads some textual data from DB. A user is presented with this data, and can add an annotation to the data - it then gets added to DB, and user is presented with status of addition (it could fail, so this outcome needs to be presented).

My biggest problem is that I don't know how to approach dynamically creating and assigning observeEvents, and then managing them. In case the user selected different set of filters, I have no idea on how to remove existing observeEvents - since they are dumped in server's body, and are not assigned to any value that could be removed/updated.

My app looks like this:


dt <- tribble(
    ~ID,  ~Content, ~Note,
    'AB', 'Lorem ipsum', NA_character_,
    'BC', 'dolor sit amet', NA_character_, 
    'CD', 'consectetur adipiscing', NA_character_,
    'DE', 'sed do eiusmod', NA_character_,
    'EF', 'tempor incididunt', NA_character_,
    'FG', 'ut labore et dolore', NA_character_

# Simulate a 50% change of failure.
simulateInsert <- function() {
    ifelse(runif(1) < .5, TRUE, FALSE)

ui <- fluidPage(
    titlePanel("Dynamic Buttons"),

                        "Number of buttons:",
                        min = 3,
                        max = 6,
                        value = 4),


server <- function(input, output) {

    comm <- reactiveValues(
                           data = NULL
    # Simulate data download and filtering
                     comm$data <- dt[1:input$buttons, ]
    # Buttons and textInput creation part
    mainUI <- reactive({
        ids <- isolate(comm$data$ID)
             function(x, y)
                 output[[paste0('content', y)]] <- renderText(as.character(y))
                 output[[paste0('result', y)]] <- renderText('')
                 textOutput(paste0('content', y)),
                 textInput(paste0('txt', y), paste0('Text Input ', x)),
                 actionButton(paste0('but', y), paste0('Send', x)),
                 textOutput(paste0('result', y))
    output$mainUI <- renderUI({
                 function(x, y)
                     observeEvent(input[[paste0('but', y)]],
                                      if(simulateInsert() == TRUE) {
                                          output[[paste0('result', y)]] <- 'Success'
                                      } else{
                                          output[[paste0('result', y)]] <- 'Failed'

# Run the application 
shinyApp(ui = ui, server = server)

The last observe does not work as expected - it never executes.

I have also considered a possibility of using:

observeEvent(input[[grepl("but", names(input))]],

            ## Do... something that hmmmm... ?

But does not work because of error below. Even if it worked I am not sure how shall I sort out which button has been pressed (probably using an intermediate reactiveValues object)

Warning: Error in checkName: Must use single string to index into reactivevalues
  62: stop
  61: checkName
  60: [[.reactivevalues
  58: observeEventExpr
   1: runApp

Is there a way to do what I want that I am missing? Any suggestion is very welcome!

There is a helpful example on Stack Overflow :

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.