four-eyes
four-eyes

Reputation: 12394

Uncaught handler for message of type “…” already added

I am working with Shiny and JavaScript. I extend the functionality of Shiny with JavaScript. Doing that, I work with callbackHandlers. I observe the userinput with a click event implemented in JS. Once the event is fired, I send the needed data to R, where a function works with the data. The results again get send back to JS where the display of the data handled.

So. on my JS side I have something like this:

for(var i = 0; i < radioButtons.length; i++) {
    radioButtons[i].onclick = function() {
        if (parseInt(this.value) === 10) {
            Shiny.onInputChange("go", this.value);
            Shiny.addCustomMessageHandler("someCallbackHandler1", function(someJson) {
                someFunction(someJson);
            });

        } else if (parseInt(this.value) === 11) {
            Shiny.onInputChange("go", this.value);
            Shiny.addCustomMessageHandler("someCallbackHandler2", function(someJson) {
                someFunction(someJson);
            });
       }  // more else if checking for the value
       ....

On the R side I do this

observe({
if( !is.null(input$go) ) {
    if( (input$go == 10) ) {
        sendToJs1[["myJson"]] <- someFunctionIwrote(arg1, arg2, arg3, arg4)
        session$sendCustomMessage(type = "someCallbackHandler1", sendToJs1$myJson)

    } else if( (input$go == 11) ) {
        sendToJs2[["myJson"]] <- someFunctionIwrote(arg1, arg2, arg3, arg4, arg5, arg6)
        session$sendCustomMessage(type = "someCallbackHandler2", sendToJs2$myJson)

   } # more else if checking for which value gets send from js
   ....

When I click on the radioButton with the value 10, then on the radioButton with the value 11 and then again on the radioButton with the value 10 I get this.

Uncaught handler for message of type “ someCallbackHandler1” already added

So JS notices that the callbackHandler1 is already added and does not add it again. But I need it to be added again in order to display the data. Further, what would JS do if the input data changes and someFunctionIwrote(arg1, arg2, arg3, arg4) is executed with different input data? Of course the callbackHandler1 is already added, but whats inside, the results send from R to JS is different.

How would I manage this situation?

Upvotes: 0

Views: 53

Answers (1)

nilsole
nilsole

Reputation: 1723

My recommendation would be:

  1. Define your javascript event handlers only once, and outside your loops. No need to define them more than once. They will continuously listen to the messages from the server once they have been created.

  2. Make sure that the callback functions stated in the handlers are flexible enough to handle all your server responses. So your function someFunction() should be able to handle all possible messages from the server.

So the code would be:

// function to be called from inside the callback functions:
function someFunction(someJson){
 console.log("No matter what someJson is, I will handle them all properly!");
...
}

// set the event handlers for message from server:
Shiny.addCustomMessageHandler("someCallbackHandler1", function(someJson) {
                someFunction(someJson);
            });
Shiny.addCustomMessageHandler("someCallbackHandler2", function(someJson) {
                someFunction(someJson);
            });

// set the event handlers for radio button clicks:
for(var i = 0; i < radioButtons.length; i++) {
    radioButtons[i].onclick = function() {
        if (parseInt(this.value) === 10) {
            Shiny.onInputChange("go", this.value);
        } else if (parseInt(this.value) === 11) {
            Shiny.onInputChange("go", this.value);
       }  // more else if checking for the value

Upvotes: 1

Related Questions