Sending/Processing Multiple messages from Javascript to R

shiny

#1

I send multiple messages from the UI to the R session using Shiny.onInputChange(...). But Shiny server only sends the response to the last request back. Is there a way to process every single request and send it to the UI ?

A simple example to demonstrate would be on clicking a button, send multiple onInputChange messages. In this example i send, 10 requests to the UI, but the server only responds on the last one. (This is only to demonstrate my usecase and is not what i will be doing).

library(shiny)

app <- shinyApp(
  ui = fluidPage(
    tags$script(HTML("
        $(document).ready(function() {
          var counter = 0;

          function clickButton(){
            counter++;
            console.log(counter);
              Shiny.onInputChange('buttonClicked', {
                'counter': counter,
                '.nounce': Math.random()
              });
          }

          function clickMultiButton() {
            for(var i=0; i<10; i++) {
              clickButton();
            }
          }

          $('#clicker').click(clickMultiButton);
          
          function receivedMsg(msg) {
            console.log('message received from R');
            console.log(msg);
          }

          Shiny.addCustomMessageHandler('RMsg', receivedMsg);

        })
       ")),
    actionButton("clicker", "click!!")
  ),
  server = function(input, output, session) {
    observeEvent(session$input[["buttonClicked"]], {
      message("button is clicked. sending back response")
      
      counter <- session$input[['buttonClicked']][["counter"]]
      
      session$sendCustomMessage(type = "RMsg",  counter)
      
    })
  }
)

app

Thanks!


#2

I think it's too fast to handle the different messages for R. Adding a sleep helps

library(shiny)

ui = fluidPage(
    tags$script(HTML("
                     $(document).ready(function() {
                     var counter = 0;
                     
                     function clickButton(){
                     counter++;
                     console.log(counter);
                     Shiny.onInputChange('buttonClicked', {
                     'counter': counter,
                     '.nounce': Math.random()
                     });
                     }
                     
                     function sleep(ms) {
                        return new Promise(resolve => setTimeout(resolve, ms));
                     }
                     
                     async function clickMultiButton() {
                      for(var i=0; i<10; i++) {
                        clickButton();
                        await sleep(100);
                      }
                     }
                     
                     $('#clicker').click(clickMultiButton);
                     
                     function receivedMsg(msg) {
                     console.log('message received from R');
                     console.log(msg);
                     }
                     
                     Shiny.addCustomMessageHandler('RMsg', receivedMsg);
                     
                     })
                     ")),
    actionButton("clicker", "click!!")
  )
  
server = function(input, output, session) {
    observeEvent(session$input[["buttonClicked"]], {
      message("button is clicked. sending back response")
      
      counter <- session$input[['buttonClicked']][["counter"]]
      
      session$sendCustomMessage(type = "RMsg",  counter)
      
    })
}

shinyApp(ui, server)