I am trying to push users from a while loop into a mutable Vec. The println! inside the
while loop show that the users variable is being filled and is growing.
But when I afterwards want to send it out via Ok(users) it's empty. What I am doing wrong?
Help would be appreciated.
async fn get_all_users(pgpool: Arc<PgPool>) -> Result<Vec<User>, Error> {
let mut users: Vec<User> = Vec::new();
let mut incoming = sqlx::query_as::<_, User>(
r#"
SELECT user_id, first_name, last_name, telephone_number, email_address FROM "user"
"#,
)
.fetch(&*pgpool);
while let Ok(user) = incoming.try_next().await {
if let Some(user) = user {
users.push(user);
println!("The updated users get_all_users {:?}", &users);
}
}
if !users.is_empty() {
println!("users is not empty: {:?}", &users);
Ok(users)
} else {
println!("users is empty");
Err(Error::DbError)
}
}
I can’t see anything wrong. Maybe start with double-checking that the code you posted is exactly the code you've ran?
E.g. double-check that what you posted here is an accurate copy-paste with no manual edits that could remove the mistake; tweak the printed messages in a noticeable way, and check that those changes are visible when executing, so you can rule out that you just missed saving the files and/or re-building your project, or you're editing a different clone of your project than the one you're executing, or things like that.
Perhaps you could also clarify what exactly you mean by this. On first read I’ve assumed that you mean you’re hitting the users is empty case/printout (because you mentioned, for contrast, explicitly only the “println! in the while loop”), but if you instead are speaking of observed program behavior around the call site of get_all_users, then your mistake could of course simply be there, right?
Thanks for the suggestion. The try_next gives a Result, so I still need to use Ok first. This in turn returns an Option. Is this correct?
while let Ok(user_incoming) = incoming.try_next().await {
if let Some(user_incoming) = user_incoming {
let _ = &users.push(user_incoming);
} else {
break;
}
}
The break: leaves the while loop and then I should be able to return the users wrapped in Ok, `Ok(users).
@Bruecki Thanks you for your advice. I finally understood my error in logic. This is what finally worked.
async fn get_all_user(pgpool: &PgPool) -> Result<Vec<User>, anyhow::Error> {
let mut users: Vec<User> = Vec::new();
// Here we are getting one user at a time, so we expect a User and not a Vec<User>
let mut records = sqlx::query_as::<_, User>(
r#"
SELECT user_id, first_name, last_name, telephone_number, email_address from "user"
"#,
)
.fetch(pgpool);
while let Some(record) = &records.try_next().await? {
let _ = &users.push(record.clone());
}
Ok(users)
}