rustwasm / wasm-bindgen

Facilitating high-level interactions between Wasm modules and JavaScript

Home Page:https://rustwasm.github.io/docs/wasm-bindgen/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Providing a closure as member of a parameter object to pass to an JS function

emirror-de opened this issue · comments

Summary

Dear Community,
I want to create bindings for the Modal module of fomantic-ui.

The following example is shown for a confirm modal in the documentation:

// title and handler
$.modal(
    'confirm',
    {
        title: 'Ready?',
        handler: function(choice) {
            $.toast({
                message: 'You ' + (choice ? 'Accepted':'Declined')
            });
        }
    }
);

The configuration object contains a handler callback.

How is it possible to create a binding for this? As far as I know, there is no method using serde for this because a closure is required.

I tried:

/// [Modal] configuration options.
#[wasm_bindgen]
pub struct ModalConfig {
    /// Title of the modal.
    title: String,
    /// Handler.
    handler: Closure<dyn Fn(bool)>,
}

impl ModalConfig {
    /// New modal configuration.
    pub fn new<H: Fn(bool) + 'static>(title: &str, handler: H) -> Self {
        let handler = Closure::new(handler);
        Self {
            title: title.to_string(),
	    handler
        }
    }
}

#[wasm_bindgen]
extern "C" {
    /// A modal.
    pub type Modal;
    
    /// Internal function to create the modal on JavaScript side.
    #[wasm_bindgen(js_namespace=["$"], js_name="modal")]
    fn new_modal_with_config(props: &str, config: ModalConfig) -> Modal;
}

impl Modal {
    /// A new modal with given configuration.
    pub fn new_with_config(config: ModalConfig) -> Self {
        new_modal_with_config("confirm", config)
    }
}

In my leptos component, I am using:

let config = ModalConfig::new(
	"hello",
        move |b| {
            log::debug!("HI {b}");
        }
);
let modal = Modal::new_with_config(config);

The code compiles, the modal opens, but there is neither a title, nor does the callback fire when I hit the "OK" button.

Can someone help me to make this work? What I am doing wrong?

Thanks in advance, best regards,
Lewin