@@ -87,9 +87,28 @@ export function reactShinyInput(selector,
8787 return this . getInputValue ( el ) ;
8888 }
8989 setValue ( el , value , rateLimited = false ) {
90- this . setInputValue ( el , value ) ;
91- this . getCallback ( el ) ( rateLimited ) ;
92- this . render ( el ) ;
90+ /*
91+ * We have to check whether $(el).data('callback') is undefined here
92+ * in case shiny::renderUI() is involved. If an input is contained in a
93+ * shiny::uiOutput(), the following strange thing happens occasionally:
94+ *
95+ * 1. setValue() is bound to an el in this.render(), below
96+ * 2. An event that will call setValue() is enqueued
97+ * 3. While the event is still enqueued, el is unbound and removed
98+ * from the DOM by the JS code associated with shiny::uiOutput()
99+ * - That code uses jQuery .html() in output_binding_html.js
100+ * - .html() removes el from the DOM and clears ist data and events
101+ * 4. By the time the setValue() bound to the original el is invoked,
102+ * el has been unbound and its data cleared.
103+ *
104+ * Since the original input is gone along with its callback, it
105+ * seems to make the most sense to do nothing.
106+ */
107+ if ( $ ( el ) . data ( 'callback' ) !== undefined ) {
108+ this . setInputValue ( el , value ) ;
109+ this . getCallback ( el ) ( rateLimited ) ;
110+ this . render ( el ) ;
111+ }
93112 }
94113 initialize ( el ) {
95114 $ ( el ) . data ( 'value' , JSON . parse ( $ ( el ) . next ( ) . text ( ) ) ) ;
@@ -99,7 +118,7 @@ export function reactShinyInput(selector,
99118 $ ( el ) . data ( 'callback' , callback ) ;
100119 this . render ( el ) ;
101120 }
102- unsubscribe ( el , callback ) {
121+ unsubscribe ( el ) {
103122 ReactDOM . render ( null , el ) ;
104123 }
105124 receiveMessage ( el , data ) {
0 commit comments