Skip to content

Commit

Permalink
Add a way to detect if server fn is coming from a client with wasm di…
Browse files Browse the repository at this point in the history
…sabled
  • Loading branch information
SleeplessOne1917 committed Jan 12, 2024
1 parent a4f2ac5 commit 5b056a7
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 22 deletions.
16 changes: 7 additions & 9 deletions examples/action-form-error-handling/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,10 @@ async fn do_something(should_error: Option<String>) -> Result<String, ServerFnEr
#[component]
fn HomePage() -> impl IntoView {
let do_something_action = Action::<DoSomething, _>::server();
let error = RwSignal::new(None);
let value = Signal::derive(move || do_something_action.value().get().unwrap_or_else(|| Ok(String::new())));

Effect::new_isomorphic(move |_| {
with!(|error| {
logging::log!("Got error in app: {error:?}");
})
logging::log!("Got value = {:?}", value.get());
});

view! {
Expand All @@ -60,12 +58,12 @@ fn HomePage() -> impl IntoView {
.1.into_inner()
.to_string())
>
{do_something_action.value()}
{value}
<ActionForm action=do_something_action class="form">
<label>Should error: <input type="checkbox" name="should_error"/></label>
<button type="submit">Submit</button>
</ActionForm>
</ErrorBoundary>
<ActionForm action=do_something_action class="form" error=error>
<label>Should error: <input type="checkbox" name="should_error"/></label>
<button type="submit">Submit</button>
</ActionForm>
}
}

Expand Down
9 changes: 8 additions & 1 deletion integrations/actix/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,8 @@ pub fn handle_server_fns_with_context(
Encoding::GetJSON | Encoding::GetCBOR => query,
};

leptos::logging::log!("In server fn before resp with data = {data:?}");

let res = match server_fn.call((), data).await {
Ok(serialized) => {
let res_options =
Expand All @@ -246,6 +248,7 @@ pub fn handle_server_fns_with_context(
!= Some("application/x-www-form-urlencoded")
&& accept_header != Some("application/cbor")
{
leptos::logging::log!("Will redirect for form submit");
// Location will already be set if redirect() has been used
let has_location_set = res_parts
.headers
Expand All @@ -264,7 +267,7 @@ pub fn handle_server_fns_with_context(
))
.content_type("application/json");
}
};
}
// Override StatusCode if it was set in a Resource or Element
if let Some(status) = res_parts.status {
res.status(status);
Expand All @@ -282,16 +285,19 @@ pub fn handle_server_fns_with_context(

match serialized {
Payload::Binary(data) => {
leptos::logging::log!("serverfn return bin = {data:?}");
res.content_type("application/cbor");
res.body(Bytes::from(data))
}
Payload::Url(data) => {
leptos::logging::log!("serverfn return url = {data:?}");
res.content_type(
"application/x-www-form-urlencoded",
);
res.body(data)
}
Payload::Json(data) => {
leptos::logging::log!("serverfn return json = {data:?}");
res.content_type("application/json");
res.body(data)
}
Expand Down Expand Up @@ -324,6 +330,7 @@ pub fn handle_server_fns_with_context(
}
}
};
leptos::logging::log!("done serverfn with status {}", res.status());
// clean up the scope
runtime.dispose();
res
Expand Down
51 changes: 39 additions & 12 deletions router/src/components/form.rs
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ pub fn ActionForm<I, O>(
#[prop(optional, into)]
attributes: Vec<(&'static str, Attribute)>,
/// Component children; should include the HTML of the form elements.
children: Children,
children: ChildrenFn,
) -> impl IntoView
where
I: Clone + ServerFn + 'static,
Expand All @@ -452,19 +452,46 @@ where
let input = action.input();

let effect_action_url = action_url.clone();
Effect::new_isomorphic(move |_| {
let errors = use_context::<HashSet<ServerFnUrlError>>();

let children = Box::new(move || {
let wasm_has_loaded = RwSignal::new(false);
let children = StoredValue::new(children);
let action_url = effect_action_url.clone();

Effect::new_isomorphic(move |_| {
let errors = use_context::<HashSet<ServerFnUrlError>>();
if let Some(url_error) =
errors
.map(|errors| {
errors
.into_iter()
.find(|e| effect_action_url.contains(e.fn_name()))
})
.flatten() {
leptos::logging::log!("In iso effect with error = {url_error:?}");
value.try_set(Some(Err(url_error.error().clone())));
}
.map(|errors| {
errors
.into_iter()
.find(|e| effect_action_url.contains(e.fn_name()))
})
.flatten() {
leptos::logging::log!("In iso effect with error = {url_error:?}");
value.try_set(Some(Err(url_error.error().clone())));
}
});

Effect::new(move |_| {
leptos::logging::log!("In browser action form effect");
wasm_has_loaded.set(true);
});

view!{
<input
id={format!("leptos_wasm_has_loaded_{}", action_url.split('/').last().unwrap_or(""))}
name="leptos_wasm_has_loaded"
type="hidden"
value=move || with!(|wasm_has_loaded|
if *wasm_has_loaded {
"true"
} else {
"false"
})
/>
{with!(|children| children())}
}
});

let on_error = Rc::new(move |e: &gloo_net::Error| {
Expand Down

0 comments on commit 5b056a7

Please sign in to comment.