Stophface Stophface - 1 month ago 8
R Question

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?

Answer

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
Comments