Difference between lapply and for loops in creating dynamic observers

I have always wondered, why we must use lapply instead of for loops to create dynamic observers. Let's say that I am inserting 5 buttons on a click of another button and create 5 observeEvents respectively to react to each button click.
When I use an equivalent for loop instead of a lapply, only the last observeEvent (5th button) is triggered (but 5x times for some reason). When I use a lapply, all buttons react once upon corresponding clicks. I wonder, why this is the case? What is the logic behind this?

# An example based on http://shiny.rstudio.com/articles/dynamic-ui.html


ui = basicPage(
    actionButton(inputId = "add_buttons", label = "Add 5 Buttons")
  uiOutput("more_buttons") # this is where the dynamically added buttons will go.

server = function(input, output)
  # We need to track the actionButtons and their respective observeEvents
  rvs = reactiveValues(buttons = list(), observers = list()) 
    l = length(rvs$buttons) + 1
    for(i in l:(l+4)) {
      rvs$buttons[[i]] = actionButton(inputId = paste0("button",i), label = i)
    #rvs$observers = lapply(
     for(i in l:(l+4)){ 
      #function(i) {
     	rvs$observers[[i]] = observeEvent(input[[paste0("button",i)]], 
                     print(sprintf("You clicked button number %d",i))
  output$more_buttons = renderUI({
    do.call(fluidRow, rvs$buttons) # Add the dynamic buttons into a single fluidRow

shinyApp(ui, server)

Based on this example here: https://gist.githubusercontent.com/mine-cetinkaya-rundel/0fe2a9830f7151e72053239e73350592/raw/56eebeb5e854ef2cb55133eef543c2cd51b5dede/app.R


Please see this:

and this:


To prove the point mentioned in the references stackoverflow asnwer, I set i = 1 right after the loop and yes, now it triggers exactly only when the first button is pressed (5x times!) instead of the last button.

1 Like

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.