mirror of
https://github.com/leptos-rs/leptos.git
synced 2025-12-28 09:02:37 -05:00
Compare commits
1 Commits
actionform
...
gbj-patch-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8943539043 |
@@ -97,15 +97,24 @@ args = ["+nightly", "doc"]
|
||||
cwd = "leptos_macro/example"
|
||||
install_crate = false
|
||||
|
||||
[tasks.ci-examples]
|
||||
[tasks.test-examples]
|
||||
description = "Run all unit and web tests for examples"
|
||||
cwd = "examples"
|
||||
command = "cargo"
|
||||
args = ["make", "ci-clean"]
|
||||
args = ["make", "test-unit-and-web"]
|
||||
|
||||
[tasks.verify-examples]
|
||||
description = "Run all quality checks and tests for examples"
|
||||
env = { CLEAN_AFTER_VERIFY = "true" }
|
||||
cwd = "examples"
|
||||
command = "cargo"
|
||||
args = ["make", "verify-flow"]
|
||||
|
||||
[tasks.clean-examples]
|
||||
description = "Clean all example projects"
|
||||
cwd = "examples"
|
||||
command = "cargo"
|
||||
args = ["make", "clean"]
|
||||
args = ["make", "clean-all"]
|
||||
|
||||
[env]
|
||||
RUSTFLAGS = ""
|
||||
|
||||
@@ -124,7 +124,7 @@ You can go even deeper. Say you want to have tabs for each contact’s address,
|
||||
|
||||
## `<Outlet/>`
|
||||
|
||||
Parent routes do not automatically render their nested routes. After all, they are just components; they don’t know exactly where they should render their children, and “just stick it at the end of the parent component” is not a great answer.
|
||||
Parent routes do not automatically render their nested routes. After all, they are just components; they don’t know exactly where they should render their children, and “just stick at at the end of the parent component” is not a great answer.
|
||||
|
||||
Instead, you tell a parent component where to render any nested components with an `<Outlet/>` component. The `<Outlet/>` simply renders one of two things:
|
||||
|
||||
|
||||
@@ -70,9 +70,9 @@ let id = move || {
|
||||
This can get a little messy: deriving a signal that wraps an `Option<_>` or `Result<_>` can involve a couple steps. But it’s worth doing this for two reasons:
|
||||
|
||||
1. It’s correct, i.e., it forces you to consider the cases, “What if the user doesn’t pass a value for this query field? What if they pass an invalid value?”
|
||||
2. It’s performant. Specifically, when you navigate between different paths that match the same `<Route/>` with only params or the query changing, you can get fine-grained updates to different parts of your app without rerendering. For example, navigating between different contacts in our contact-list example does a targeted update to the name field (and eventually contact info) without needing to replace or rerender the wrapping `<Contact/>`. This is what fine-grained reactivity is for.
|
||||
2. It’s performant. Specifically, when you navigate between different paths that match the same `<Route/>` with only params or the query changing, you can get fine-grained updates to different parts of your app without rerendering. For example, navigating between different contacts in our contact-list example does a targeted update to the name field (and eventually contact info) without needing to replacing or rerender the wrapping `<Contact/>`. This is what fine-grained reactivity is for.
|
||||
|
||||
> This is the same example from the previous section. The router is such an integrated system that it makes sense to provide a single example highlighting multiple features, even if we haven’t explained them all yet.
|
||||
> This is the same example from the previous section. The router is such an integrated system that it makes sense to provide a single example highlighting multiple features, even if we haven’t explain them all yet.
|
||||
|
||||
[Click to open CodeSandbox.](https://codesandbox.io/p/sandbox/16-router-fy4tjv?file=%2Fsrc%2Fmain.rs&selection=%5B%7B%22endColumn%22%3A1%2C%22endLineNumber%22%3A3%2C%22startColumn%22%3A1%2C%22startLineNumber%22%3A3%7D%5D)
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# The `<Form/>` Component
|
||||
|
||||
Links and forms sometimes seem completely unrelated. But, in fact, they work in very similar ways.
|
||||
Links and forms sometimes seem completely unrelated. But in fact, they work in very similar ways.
|
||||
|
||||
In plain HTML, there are three ways to navigate to another page:
|
||||
|
||||
1. An `<a>` element that links to another page: Navigates to the URL in its `href` attribute with the `GET` HTTP method.
|
||||
2. A `<form method="GET">`: Navigates to the URL in its `action` attribute with the `GET` HTTP method and the form data from its inputs encoded in the URL query string.
|
||||
3. A `<form method="POST">`: Navigates to the URL in its `action` attribute with the `POST` HTTP method and the form data from its inputs encoded in the body of the request.
|
||||
1. An `<a>` element that links to another page. Navigates to the URL in its `href` attribute with the `GET` HTTP method.
|
||||
2. A `<form method="GET">`. Navigates to the URL in its `action` attribute with the `GET` HTTP method and the form data from its inputs encoded in the URL query string.
|
||||
3. A `<form method="POST">`. Navigates to the URL in its `action` attribute with the `POST` HTTP method and the form data from its inputs encoded in the body of the request.
|
||||
|
||||
Since we have a client-side router, we can do client-side link navigations without reloading the page, i.e., without a full round-trip to the server and back. It makes sense that we can do client-side form navigations in the same way.
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
[tasks.integration-test]
|
||||
dependencies = ["cargo-leptos-e2e"]
|
||||
[tasks.test-e2e]
|
||||
dependencies = ["setup-node", "cargo-leptos-e2e"]
|
||||
|
||||
[tasks.cargo-leptos-e2e]
|
||||
command = "cargo"
|
||||
args = ["leptos", "end-to-end"]
|
||||
[tasks.clean-all]
|
||||
dependencies = ["clean-cargo", "clean-node_modules", "clean-playwright"]
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
[tasks.clean]
|
||||
dependencies = [
|
||||
"clean-cargo",
|
||||
"clean-trunk",
|
||||
"clean-node_modules",
|
||||
"clean-playwright",
|
||||
]
|
||||
|
||||
[tasks.clean-cargo]
|
||||
command = "cargo"
|
||||
args = ["clean"]
|
||||
|
||||
[tasks.clean-trunk]
|
||||
command = "trunk"
|
||||
args = ["clean"]
|
||||
|
||||
[tasks.clean-node_modules]
|
||||
script = '''
|
||||
project_dir=${PWD##*/}
|
||||
if [ "$project_dir" != "todomvc" ]; then
|
||||
find . -type d -name node_modules | xargs rm -rf
|
||||
fi
|
||||
'''
|
||||
|
||||
[tasks.clean-playwright]
|
||||
script = '''
|
||||
find . -name playwright-report -name playwright -name test-results | xargs rm -rf
|
||||
'''
|
||||
98
examples/cargo-make/common.toml
Normal file
98
examples/cargo-make/common.toml
Normal file
@@ -0,0 +1,98 @@
|
||||
[tasks.pre-clippy]
|
||||
env = { CARGO_MAKE_CLIPPY_ARGS = "--all-targets --all-features -- -D warnings" }
|
||||
|
||||
[tasks.check-style]
|
||||
description = "Check for style violations"
|
||||
dependencies = ["check-format-flow", "clippy-flow"]
|
||||
|
||||
[tasks.check-format]
|
||||
env = { LEPTOS_PROJECT_DIRECTORY = "../../" }
|
||||
args = ["fmt", "--", "--check", "--config-path", "${LEPTOS_PROJECT_DIRECTORY}"]
|
||||
|
||||
[tasks.clean-cargo]
|
||||
description = "Runs the cargo clean command."
|
||||
category = "Cleanup"
|
||||
command = "cargo"
|
||||
args = ["clean"]
|
||||
|
||||
[tasks.clean-trunk]
|
||||
description = "Runs the trunk clean command."
|
||||
category = "Cleanup"
|
||||
command = "trunk"
|
||||
args = ["clean"]
|
||||
|
||||
[tasks.clean-node_modules]
|
||||
description = "Delete all node_modules directories"
|
||||
category = "Cleanup"
|
||||
script = '''
|
||||
find . -type d -name node_modules | xargs rm -rf
|
||||
'''
|
||||
|
||||
[tasks.clean-playwright]
|
||||
description = "Delete playwright directories"
|
||||
category = "Cleanup"
|
||||
script = '''
|
||||
for pw_dir in $(find . -name playwright.config.ts | xargs dirname)
|
||||
do
|
||||
rm -rf $pw_dir/playwright-report pw_dir/playwright pw_dir/test-results
|
||||
done
|
||||
'''
|
||||
|
||||
[tasks.clean-all]
|
||||
description = "Delete all temporary directories"
|
||||
category = "Cleanup"
|
||||
dependencies = ["clean-cargo"]
|
||||
|
||||
[tasks.test-wasm]
|
||||
env = { CARGO_MAKE_WASM_TEST_ARGS = "--headless --chrome" }
|
||||
command = "cargo"
|
||||
args = ["make", "wasm-pack-test"]
|
||||
|
||||
[tasks.cargo-leptos-e2e]
|
||||
description = "Runs end to end tests with cargo leptos"
|
||||
command = "cargo"
|
||||
args = ["leptos", "end-to-end"]
|
||||
|
||||
[tasks.setup-node]
|
||||
description = "Install node dependencies and playwright browsers"
|
||||
env = { PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD = "1" }
|
||||
script = '''
|
||||
BOLD="\e[1m"
|
||||
GREEN="\e[0;32m"
|
||||
RED="\e[0;31m"
|
||||
RESET="\e[0m"
|
||||
|
||||
project_dir=$CARGO_MAKE_WORKING_DIRECTORY
|
||||
|
||||
# Discover commands
|
||||
if command -v pnpm; then
|
||||
NODE_CMD=pnpm
|
||||
PLAYWRIGHT_CMD=pnpm
|
||||
elif command -v npm; then
|
||||
NODE_CMD=npm
|
||||
PLAYWRIGHT_CMD=npx
|
||||
else
|
||||
echo "${RED}${BOLD}ERROR${RESET} - pnpm or npm is required by this task"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Install node dependencies
|
||||
for node_path in $(find . -name package.json -not -path '*/node_modules/*')
|
||||
do
|
||||
node_dir=$(dirname $node_path)
|
||||
echo Install node dependencies for $node_dir
|
||||
cd $node_dir
|
||||
${NODE_CMD} install
|
||||
cd ${project_dir}
|
||||
done
|
||||
|
||||
# Install playwright browsers
|
||||
for pw_path in $(find . -name playwright.config.ts)
|
||||
do
|
||||
pw_dir=$(dirname $pw_path)
|
||||
echo Install playwright browsers for $pw_dir
|
||||
cd $pw_dir
|
||||
${PLAYWRIGHT_CMD} playwright install
|
||||
cd $project_dir
|
||||
done
|
||||
'''
|
||||
@@ -1,9 +0,0 @@
|
||||
[tasks.pre-clippy]
|
||||
env = { CARGO_MAKE_CLIPPY_ARGS = "--all-targets --all-features -- -D warnings" }
|
||||
|
||||
[tasks.check-style]
|
||||
dependencies = ["check-format-flow", "clippy-flow"]
|
||||
|
||||
[tasks.check-format]
|
||||
env = { LEPTOS_PROJECT_DIRECTORY = "../../" }
|
||||
args = ["fmt", "--", "--check", "--config-path", "${LEPTOS_PROJECT_DIRECTORY}"]
|
||||
@@ -1,32 +1,35 @@
|
||||
extend = [
|
||||
{ path = "../cargo-make/clean.toml" },
|
||||
{ path = "../cargo-make/lint.toml" },
|
||||
{ path = "../cargo-make/node.toml" },
|
||||
]
|
||||
|
||||
# CI Stages
|
||||
extend = [{ path = "../cargo-make/common.toml" }]
|
||||
|
||||
[tasks.ci]
|
||||
dependencies = ["prepare", "lint", "build", "test-flow", "integration-test"]
|
||||
|
||||
[tasks.ci-clean]
|
||||
dependencies = ["ci", "clean"]
|
||||
|
||||
[tasks.prepare]
|
||||
dependencies = ["setup-node"]
|
||||
|
||||
[tasks.lint]
|
||||
dependencies = ["check-style"]
|
||||
|
||||
[tasks.integration-test]
|
||||
|
||||
# ALIASES
|
||||
alias = "verify-flow"
|
||||
|
||||
[tasks.verify-flow]
|
||||
alias = "ci"
|
||||
description = "Provides pre and post hooks for verify"
|
||||
dependencies = ["pre-verify", "verify", "post-verify"]
|
||||
|
||||
[tasks.t]
|
||||
dependencies = ["test-flow"]
|
||||
[tasks.verify]
|
||||
description = "Run all quality checks and tests"
|
||||
dependencies = ["check-style", "test-unit-and-e2e"]
|
||||
|
||||
[tasks.it]
|
||||
alias = "integration-test"
|
||||
[tasks.test-unit-and-e2e]
|
||||
description = "Run all unit and e2e tests"
|
||||
dependencies = ["test-flow", "test-e2e-flow"]
|
||||
|
||||
[tasks.pre-verify]
|
||||
|
||||
[tasks.post-verify]
|
||||
dependencies = ["maybe-clean-all"]
|
||||
|
||||
[tasks.maybe-clean-all]
|
||||
description = "Used to clean up locally after call to verify-examples"
|
||||
condition = { env_true = ["CLEAN_AFTER_VERIFY"] }
|
||||
|
||||
[tasks.test-e2e-flow]
|
||||
description = "Provides pre and post hooks for test-e2e"
|
||||
dependencies = ["pre-test-e2e", "test-e2e", "post-test-e2e"]
|
||||
|
||||
[tasks.pre-test-e2e]
|
||||
|
||||
[tasks.test-e2e]
|
||||
|
||||
[tasks.post-test-e2e]
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
[tasks.setup-node]
|
||||
description = "Install node dependencies and playwright browsers"
|
||||
env = { PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD = "1" }
|
||||
script = '''
|
||||
BOLD="\e[1m"
|
||||
GREEN="\e[0;32m"
|
||||
RED="\e[0;31m"
|
||||
RESET="\e[0m"
|
||||
|
||||
project_dir=$CARGO_MAKE_WORKING_DIRECTORY
|
||||
|
||||
# Discover commands
|
||||
if command -v pnpm; then
|
||||
NODE_CMD=pnpm
|
||||
PLAYWRIGHT_CMD=pnpm
|
||||
elif command -v npm; then
|
||||
NODE_CMD=npm
|
||||
PLAYWRIGHT_CMD=npx
|
||||
else
|
||||
echo "${RED}${BOLD}ERROR${RESET} - pnpm or npm is required by this task"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Install node dependencies
|
||||
for node_path in $(find . -name package.json -not -path '*/node_modules/*')
|
||||
do
|
||||
node_dir=$(dirname $node_path)
|
||||
echo Install node dependencies for $node_dir
|
||||
cd $node_dir
|
||||
${NODE_CMD} install
|
||||
cd ${project_dir}
|
||||
done
|
||||
|
||||
# Install playwright browsers
|
||||
for pw_path in $(find . -name playwright.config.ts)
|
||||
do
|
||||
pw_dir=$(dirname $pw_path)
|
||||
echo Install playwright browsers for $pw_dir
|
||||
cd $pw_dir
|
||||
${PLAYWRIGHT_CMD} playwright install
|
||||
cd $project_dir
|
||||
done
|
||||
'''
|
||||
@@ -1,4 +1,7 @@
|
||||
extend = [{ path = "../cargo-make/playwright.toml" }]
|
||||
|
||||
[tasks.integration-test]
|
||||
dependencies = ["test-playwright-autostart"]
|
||||
[tasks.test-e2e]
|
||||
dependencies = ["setup-node", "test-playwright-autostart"]
|
||||
|
||||
[tasks.clean-all]
|
||||
dependencies = ["clean-cargo", "clean-node_modules", "clean-playwright"]
|
||||
|
||||
@@ -1,8 +1,22 @@
|
||||
[tasks.clean-playwright]
|
||||
description = "Delete playwright directories"
|
||||
category = "Cleanup"
|
||||
script = '''
|
||||
for pw_dir in $(find . -name playwright.config.ts | xargs dirname)
|
||||
do
|
||||
rm -rf $pw_dir/playwright-report pw_dir/playwright pw_dir/test-results
|
||||
done
|
||||
'''
|
||||
|
||||
[tasks.test-playwright-autostart]
|
||||
description = "Run playwright test with server autostart"
|
||||
category = "Test"
|
||||
command = "npm"
|
||||
args = ["run", "e2e:auto-start"]
|
||||
|
||||
[tasks.test-playwright]
|
||||
description = "Run playwright test"
|
||||
category = "Test"
|
||||
script = '''
|
||||
BOLD="\e[1m"
|
||||
GREEN="\e[0;32m"
|
||||
@@ -32,6 +46,8 @@ done
|
||||
'''
|
||||
|
||||
[tasks.test-playwright-ui]
|
||||
description = "Run playwright test --ui"
|
||||
category = "Test"
|
||||
script = '''
|
||||
BOLD="\e[1m"
|
||||
GREEN="\e[0;32m"
|
||||
@@ -61,6 +77,8 @@ done
|
||||
'''
|
||||
|
||||
[tasks.test-playwright-report]
|
||||
description = "Run playwright show-report"
|
||||
category = "Test"
|
||||
script = '''
|
||||
BOLD="\e[1m"
|
||||
GREEN="\e[0;32m"
|
||||
|
||||
@@ -2,9 +2,13 @@
|
||||
command = "trunk"
|
||||
args = ["build"]
|
||||
|
||||
[tasks.clean-trunk]
|
||||
command = "trunk"
|
||||
args = ["clean"]
|
||||
|
||||
[tasks.start-trunk]
|
||||
command = "trunk"
|
||||
args = ["serve", "${@}"]
|
||||
args = ["serve", "--open"]
|
||||
|
||||
[tasks.stop-trunk]
|
||||
script = '''
|
||||
|
||||
@@ -5,7 +5,5 @@ condition = { env_true = ["RUN_CARGO_TEST"] }
|
||||
[tasks.post-test]
|
||||
dependencies = ["test-wasm"]
|
||||
|
||||
[tasks.test-wasm]
|
||||
env = { CARGO_MAKE_WASM_TEST_ARGS = "--headless --chrome" }
|
||||
command = "cargo"
|
||||
args = ["make", "wasm-pack-test"]
|
||||
[tasks.clean-all]
|
||||
dependencies = ["clean-cargo", "clean-trunk"]
|
||||
|
||||
@@ -841,7 +841,9 @@ where
|
||||
crate::console_warn(
|
||||
"You have both `csr` and `ssr` or `hydrate` and `ssr` enabled as \
|
||||
features, which may cause issues like <Suspense/>` failing to work \
|
||||
silently.",
|
||||
silently. `csr` is enabled by default on `leptos`, and can be \
|
||||
disabled by adding `default-features = false` to your `leptos` \
|
||||
dependency.",
|
||||
);
|
||||
|
||||
cfg_if! {
|
||||
|
||||
@@ -368,7 +368,9 @@ impl View {
|
||||
crate::console_error(
|
||||
"\n[DANGER] You have both `csr` and `ssr` or `hydrate` and `ssr` \
|
||||
enabled as features, which may cause issues like <Suspense/>` \
|
||||
failing to work silently.\n",
|
||||
failing to work silently. `csr` is enabled by default on \
|
||||
`leptos`, and can be disabled by adding `default-features = \
|
||||
false` to your `leptos` dependency.\n",
|
||||
);
|
||||
|
||||
self.render_to_string_helper(false)
|
||||
|
||||
@@ -59,7 +59,9 @@ pub fn render_to_stream_in_order_with_prefix(
|
||||
crate::console_error(
|
||||
"\n[DANGER] You have both `csr` and `ssr` or `hydrate` and `ssr` \
|
||||
enabled as features, which may cause issues like <Suspense/>` \
|
||||
failing to work silently.\n",
|
||||
failing to work silently. `csr` is enabled by default on `leptos`, \
|
||||
and can be disabled by adding `default-features = false` to your \
|
||||
`leptos` dependency.\n",
|
||||
);
|
||||
|
||||
let (stream, runtime, _) =
|
||||
|
||||
@@ -215,7 +215,6 @@ where
|
||||
error.try_set(None);
|
||||
}
|
||||
if let Some(on_response) = on_response.clone() {
|
||||
leptos::log!("running on_response");
|
||||
on_response(resp.as_raw());
|
||||
}
|
||||
// Check all the logical 3xx responses that might
|
||||
@@ -426,67 +425,70 @@ where
|
||||
let on_response = Rc::new(move |resp: &web_sys::Response| {
|
||||
let resp = resp.clone().expect("couldn't get Response");
|
||||
spawn_local(async move {
|
||||
let body = JsFuture::from(
|
||||
resp.text().expect("couldn't get .text() from Response"),
|
||||
)
|
||||
.await;
|
||||
let status = resp.status();
|
||||
match body {
|
||||
Ok(json) => {
|
||||
let json = json
|
||||
.as_string()
|
||||
.expect("couldn't get String from JsString");
|
||||
if (500..=599).contains(&status) {
|
||||
match serde_json::from_str::<ServerFnError>(&json) {
|
||||
Ok(res) => {
|
||||
value.try_set(Some(Err(res)));
|
||||
if let Some(error) = error {
|
||||
error.try_set(None);
|
||||
let redirected = resp.redirected();
|
||||
if !redirected {
|
||||
let body = JsFuture::from(
|
||||
resp.text().expect("couldn't get .text() from Response"),
|
||||
)
|
||||
.await;
|
||||
let status = resp.status();
|
||||
match body {
|
||||
Ok(json) => {
|
||||
let json = json
|
||||
.as_string()
|
||||
.expect("couldn't get String from JsString");
|
||||
if (500..=599).contains(&status) {
|
||||
match serde_json::from_str::<ServerFnError>(&json) {
|
||||
Ok(res) => {
|
||||
value.try_set(Some(Err(res)));
|
||||
if let Some(error) = error {
|
||||
error.try_set(None);
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
value.try_set(Some(Err(
|
||||
ServerFnError::Deserialization(
|
||||
e.to_string(),
|
||||
),
|
||||
)));
|
||||
if let Some(error) = error {
|
||||
error.try_set(Some(Box::new(e)));
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
value.try_set(Some(Err(
|
||||
ServerFnError::Deserialization(
|
||||
e.to_string(),
|
||||
),
|
||||
)));
|
||||
if let Some(error) = error {
|
||||
error.try_set(Some(Box::new(e)));
|
||||
} else {
|
||||
match serde_json::from_str::<O>(&json) {
|
||||
Ok(res) => {
|
||||
value.try_set(Some(Ok(res)));
|
||||
if let Some(error) = error {
|
||||
error.try_set(None);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
match serde_json::from_str::<O>(&json) {
|
||||
Ok(res) => {
|
||||
value.try_set(Some(Ok(res)));
|
||||
if let Some(error) = error {
|
||||
error.try_set(None);
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
value.try_set(Some(Err(
|
||||
ServerFnError::Deserialization(
|
||||
e.to_string(),
|
||||
),
|
||||
)));
|
||||
if let Some(error) = error {
|
||||
error.try_set(Some(Box::new(e)));
|
||||
Err(e) => {
|
||||
value.try_set(Some(Err(
|
||||
ServerFnError::Deserialization(
|
||||
e.to_string(),
|
||||
),
|
||||
)));
|
||||
if let Some(error) = error {
|
||||
error.try_set(Some(Box::new(e)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
error!("{e:?}");
|
||||
if let Some(error) = error {
|
||||
error.try_set(Some(Box::new(
|
||||
ServerFnErrorErr::Request(
|
||||
e.as_string().unwrap_or_default(),
|
||||
),
|
||||
)));
|
||||
Err(e) => {
|
||||
error!("{e:?}");
|
||||
if let Some(error) = error {
|
||||
error.try_set(Some(Box::new(
|
||||
ServerFnErrorErr::Request(
|
||||
e.as_string().unwrap_or_default(),
|
||||
),
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
cx.batch(move || {
|
||||
input.try_set(None);
|
||||
action.set_pending(false);
|
||||
|
||||
Reference in New Issue
Block a user