I'm building an app in Leptos where I want the UI to load an initial value from the server (from the database), but then I want to be able to update that value in the UI and send the new value back.
I can easily create a client side-only value like so:
#[component]
fn HomePage() -> impl IntoView {
let puzzle_text = create_rw_signal("".to_string());
let save_puzzle = create_action(|input: &String| {
let input = input.clone();
async move {
set_puzzle(1, input).await // <-- server function
}
});
view! {
<h1>"Here's the puzzle!"</h1>
<input type="text"
on:input=move |ev| { puzzle_text.set(event_target_value(&ev)) }
prop:value=puzzle_text
/>
<button on:click=move |_| {
save_puzzle.dispatch(puzzle_text.get());
}>"Save Puzzle"</button>
}
}
Or I can create a resource to fetch the value from the backend:
#[component]
fn HomePage() -> impl IntoView {
let initial_puzzle_text = create_resource(
|| (),
|_| async move {
get_puzzle(1).await.unwrap_or("".to_string())
}
);
let save_puzzle = create_action(...);
view! {
<h1>"Here's the puzzle!"</h1>
<Suspense fallback=move || view! { <p>"Loading"</p> }>
{move || {
initial_puzzle_text.get().map(|p| view! {
<input type="text"
prop:value=p.clone()
/>
<button on:click=move |_| {
save_puzzle.dispatch(p.clone()); // <-- doesn't update with <input/>
}>"Save Puzzle"</button>
})
}}
</Suspense>
}
}
But I can't figure out how to enable both reading the initial value from the backend and writing that value back to the backend. I feel like I'm missing something simple with RW signals.
I have tried setting the RW signal from within the resource, like so:
let puzzle_text = create_rw_signal("A".to_string());
let initial_puzzle_text = create_resource(
|| (),
|_| async move {
puzzle_text.set(get_puzzle(1).await.unwrap_or("B".to_string()));
}
);
but while I see the request hit the backend (I see a SELECT
SQL statement execute and return a result, and logging within the resource's closure works), the value of the RW signal never gets set and it keeps its initial value.
Easiest answer I've found so far: use a RW signal and make initialization an action: