#Yew Submitting a Form as JSON

1 messages · Page 1 of 1 (latest)

vagrant osprey
#

Is there an easy way to submit a form via JSON without massive boilerplate? The closest example I have seen is the following:

#[function_component(Home)]
pub fn home() -> Html {
    let registration_form = use_state(|| RegistrationForm::default());

    let username = use_node_ref();
    let first_name_ref = use_node_ref();
    let last_name_ref = use_node_ref();
    let email_ref = use_node_ref();
    let password_ref = use_node_ref();
    let confirm_password_ref = use_node_ref();

    let password_is_valid = use_state(|| true);

    log::info!("registration_form {:?}", &registration_form.clone());
    let onsubmit = {
        let registration_form = registration_form.clone();

        let username = username.clone();
        let first_name_ref = first_name_ref.clone();
        let last_name_ref = last_name_ref.clone();
        let email_ref = email_ref.clone();
        let password_ref = password_ref.clone();
        let confirm_password_ref = confirm_password_ref.clone();

        // let form_is_valid = form_is_valid.clone();
        let password_is_valid = password_is_valid.clone();
#
Callback::from(move |event: SubmitEvent| {
            event.prevent_default();

            let username = username.cast::<HtmlInputElement>().unwrap().value();
            let first_name = first_name_ref.cast::<HtmlInputElement>().unwrap().value();
            let last_name = last_name_ref.cast::<HtmlInputElement>().unwrap().value();
            let email = email_ref.cast::<HtmlInputElement>().unwrap().value();
            let password = password_ref.cast::<HtmlInputElement>().unwrap().value();
            let confirm_password = confirm_password_ref
                .cast::<HtmlInputElement>()
                .unwrap()
                .value();

            if password != confirm_password {
                password_is_valid.set(false);
                return;
            } else {
                password_is_valid.set(true);
            };

            let registration_form = RegistrationForm {
                username,
                first_name,
                last_name,
                email,
                password,
                confirm_password,
            };

            log::info!("registration_form {:?}", &registration_form);

            wasm_bindgen_futures::spawn_local(async move {
                let post_request = Request::post("https://reqres.in/api/register")
                    .headers({
                        let headers = Headers::new();
                        headers
                            // .append(name, value)
                            .set("Content-Type", "application/json");
                        headers
                    })
                    .body(JsValue::from(
                        serde_json::to_string(&registration_form).unwrap(),
                    ))
                    .send()
                    .await
                    .unwrap();

                log::info!("post_request {:?}", &post_request);
            });
        })
    };
thorn valley
#

there's not much you can do; you might want to make a custom <Input> component which should help out with some stuff. definitely not hashmap<string, string>, that would be dynamic yeah but its not very rust-idiomatic which tries to keep types for as long as possible. the solution can be for example parent node could store a RegistrationForm value, and inputs would have two Callbacks which could pull fields from that value (Callback<&RegistrationForm, AttrValue or smt>) to use in value=, and mutate the value (Callback<(AttrValue, &mut RegistrationForm)>) as action to do oninput. also custom <Form> component could provide a context where that RegistrationForm can be stored

#

so im thinking of
<Form<RegistrationForm>>
<Input<RegistrationForm>
value={ |form| form.username }
modify={ |(value, form)| form.username = value }
/>
</Form<RegistrationForm>>