#Programmatically click()ing an input element leads to a throw, any idea why?

1 messages · Page 1 of 1 (latest)

unkempt mountain
#

Hey, I have two elements button and input, like so:

<input type="button" value="Upload file" onclick={upload_clicked_callback} />
<input type="file" id="file_input" style="display: none;" onchange={file_picked_callback}/>

File input is hidden and triggered programmatically on button click with upload_clicked_callback() which calls function below.

fn on_upload_file_clicked() {
    log!("Upload clicked!");

    let window = web_sys::window().expect("should have a window in this context");
    let document = window.document().expect("window should have a document");

    let file_input_elem = document
        .get_element_by_id("file_input").expect("File input element with id \"file_input\" should exist.");
        
    let file_input_elem = file_input_elem.dyn_into::<HtmlInputElement>()
        .expect("Element should be an HtmlInputElement");

    log!("Before click");
    file_input_elem.click();
    log!("After click");
}

When I click button, an on_upload_file_clicked() starts executing and everything is fine until a simulated click file_input_elem.click();. Simulated click leads to a throw that states "Uncaught Error: closure invoked recursively or destroyed already". (screenshot attached)
Any idea what can be a cause of this? All callbacks are created with use_callback:

   let upload_clicked_callback = use_callback(move |e:MouseEvent, _| { 
        e.stop_propagation();
        on_upload_file_clicked();

   }, ());
   let file_picked_callback = use_callback(move |e: Event, _| { 
       let input = e.target_unchecked_into::<HtmlInputElement>();
       if let Some(files) = input.files() {
           if let Some(file) = files.item(0) {
               on_file_picked(File::from(file));
           }      
       }
   }, ());
summer python
#

o/ this has been reported already in https://github.com/yewstack/yew/issues/2989 and a fix is prepared in https://github.com/yewstack/yew/pull/3037
The reason is that yew installs a single event listener on root element and dispatches the event internally. This is the "closure invoked recursively" if you dispatch another event in one of the event listeners. A workaround might be to delay that dispatch (keep in mind that .click() dispatches the event synchronously), see the linked bug report for details

unkempt mountain
#

Thanks for the explanation, will check it out