diff --git a/examples/session_auth_axum/.env b/examples/session_auth_axum/.env
new file mode 100644
index 0000000000..6d8fc2c590
--- /dev/null
+++ b/examples/session_auth_axum/.env
@@ -0,0 +1 @@
+DATABASE_URL=sqlite://Todos.db
diff --git a/examples/session_auth_axum/src/error_template.rs b/examples/session_auth_axum/src/error_template.rs
index 329dfd7f4d..4f760c6b69 100644
--- a/examples/session_auth_axum/src/error_template.rs
+++ b/examples/session_auth_axum/src/error_template.rs
@@ -39,22 +39,21 @@ pub fn ErrorTemplate(
}
view! {
-
"Errors"
- {error_code.to_string()}
- "Error: " {error_string}
- }
- }
- />
+ "Errors"
+ {error_code.to_string()}
+ "Error: " {error_string}
+ }
+ }
+ />
}
}
diff --git a/examples/session_auth_axum/src/todo.rs b/examples/session_auth_axum/src/todo.rs
index 104a414174..97ad08ad6f 100644
--- a/examples/session_auth_axum/src/todo.rs
+++ b/examples/session_auth_axum/src/todo.rs
@@ -15,70 +15,56 @@ pub struct Todo {
}
cfg_if! {
-if #[cfg(feature = "ssr")] {
+ if #[cfg(feature = "ssr")] {
- use sqlx::SqlitePool;
+ use sqlx::SqlitePool;
+ use futures::future::join_all;
- pub fn pool() -> Result {
- use_context::()
- .ok_or_else(|| ServerFnError::ServerError("Pool missing.".into()))
- }
+ pub fn pool() -> Result {
+ use_context::()
+ .ok_or_else(|| ServerFnError::ServerError("Pool missing.".into()))
+ }
- pub fn auth() -> Result {
- use_context::()
- .ok_or_else(|| ServerFnError::ServerError("Auth session missing.".into()))
- }
+ pub fn auth() -> Result {
+ use_context::()
+ .ok_or_else(|| ServerFnError::ServerError("Auth session missing.".into()))
+ }
- #[derive(sqlx::FromRow, Clone)]
- pub struct SqlTodo {
- id: u32,
- user_id: i64,
- title: String,
- created_at: String,
- completed: bool,
- }
+ #[derive(sqlx::FromRow, Clone)]
+ pub struct SqlTodo {
+ id: u32,
+ user_id: i64,
+ title: String,
+ created_at: String,
+ completed: bool,
+ }
- impl SqlTodo {
- pub async fn into_todo(self, pool: &SqlitePool) -> Todo {
- Todo {
- id: self.id,
- user: User::get(self.user_id, pool).await,
- title: self.title,
- created_at: self.created_at,
- completed: self.completed,
+ impl SqlTodo {
+ pub async fn into_todo(self, pool: &SqlitePool) -> Todo {
+ Todo {
+ id: self.id,
+ user: User::get(self.user_id, pool).await,
+ title: self.title,
+ created_at: self.created_at,
+ completed: self.completed,
+ }
}
}
}
}
-}
#[server(GetTodos, "/api")]
pub async fn get_todos() -> Result, ServerFnError> {
- use futures::TryStreamExt;
-
let pool = pool()?;
- let mut todos = Vec::new();
- let mut rows =
- sqlx::query_as::<_, SqlTodo>("SELECT * FROM todos").fetch(&pool);
-
- while let Some(row) = rows.try_next().await? {
- todos.push(row);
- }
-
- // why can't we just have async closures?
- // let mut rows: Vec = rows.iter().map(|t| async { t }).collect();
-
- let mut converted_todos = Vec::with_capacity(todos.len());
-
- for t in todos {
- let todo = t.into_todo(&pool).await;
- converted_todos.push(todo);
- }
-
- let todos: Vec = converted_todos;
-
- Ok(todos)
+ Ok(join_all(
+ sqlx::query_as::<_, SqlTodo>("SELECT * FROM todos")
+ .fetch_all(&pool)
+ .await?
+ .iter()
+ .map(|todo: &SqlTodo| todo.clone().into_todo(&pool)),
+ )
+ .await)
}
#[server(AddTodo, "/api")]
@@ -94,17 +80,14 @@ pub async fn add_todo(title: String) -> Result<(), ServerFnError> {
// fake API delay
std::thread::sleep(std::time::Duration::from_millis(1250));
- match sqlx::query(
+ Ok(sqlx::query(
"INSERT INTO todos (title, user_id, completed) VALUES (?, ?, false)",
)
.bind(title)
.bind(id)
.execute(&pool)
.await
- {
- Ok(_row) => Ok(()),
- Err(e) => Err(ServerFnError::ServerError(e.to_string())),
- }
+ .map(|_| ())?)
}
// The struct name and path prefix arguments are optional.
@@ -138,51 +121,71 @@ pub fn TodoApp() -> impl IntoView {
provide_meta_context();
view! {
-
- "My Tasks"
- "Loading..."}
- >
- {move || {
- user.get().map(|user| match user {
- Err(e) => view! {
- "Signup"", "
- "Login"", "
- {format!("Login error: {}", e)}
- }.into_view(),
- Ok(None) => view! {
- "Signup"", "
- "Login"", "
- "Logged out."
- }.into_view(),
- Ok(Some(user)) => view! {
- "Settings"", "
- {format!("Logged in as: {} ({})", user.username, user.id)}
- }.into_view()
- })
- }}
+
+ "My Tasks"
+
+ "Loading..." }
+ }>
+ {move || {
+ user.get()
+ .map(|user| match user {
+ Err(e) => {
+ view! {
+ "Signup"
+ ", "
+ "Login"
+ ", "
+ {format!("Login error: {}", e)}
+ }
+ .into_view()
+ }
+ Ok(None) => {
+ view! {
+ "Signup"
+ ", "
+ "Login"
+ ", "
+ "Logged out."
+ }
+ .into_view()
+ }
+ Ok(Some(user)) => {
+ view! {
+ "Settings"
+ ", "
+
+ {format!("Logged in as: {} ({})", user.username, user.id)}
+
+ }
+ .into_view()
+ }
+ })
+ }}
+
- //Route
-
- }/>
-
- }/>
-
+ }/>
+ }/>
+ "Settings"
+
+ }
+ }
+ />
- "Settings"
-
- }/>
@@ -202,24 +205,26 @@ pub fn Todos() -> impl IntoView {
);
view! {
-
@@ -287,25 +279,32 @@ pub fn Login(
action: Action>,
) -> impl IntoView {
view! {
-
"Log In"
-
+
}
}
@@ -315,31 +314,42 @@ pub fn Signup(
action: Action>,
) -> impl IntoView {
view! {
-
"Sign Up"
-
+
}
}
@@ -349,10 +359,11 @@ pub fn Logout(
action: Action>,
) -> impl IntoView {
view! {
-
-
+
}