How to show multiple rows with Column::from_vec from a Vec<T>?

I am trying to show some rows from a table in a Postgres database. I am using SQLX alongside Iced for getting the data.

I am doing something wrong, since I get an empty window. The compiler isn’t complaining. But I don’t get the result I am looking for.

The result I want is to show muliple rows in a column![] widget.

Where am I going wrong. Any help, would be greatly appreciated.
I’ve included the parts of the code that should be relevant, but the whole main.rs is here.

This is the App’s State

#[derive(Debug, Clone, sqlx::FromRow)]
pub struct User {
user_id: uuid::Uuid,
    first_name: String,
    last_name: String,
    email_address: String,
    telephone_number: String,
}
// I have some methods on it to create a new User

#[derive(Debug, Clone)]
pub struct ExampleApp {
    pgpool: Option<Arc<PgPool>>,
    user: User,
    pub all_users: Option<Vec<User>>,
}

I have two messages ListAllUsers and ListAllUsersResult<>

#[derive(Debug, Clone)]
enum Message {
    // ...
    ListAllUsers,
    ListAllUsersResult(Result<Vec<User>, Error>),
}

Inside the fn update I handle both as follows:

fn update(&mut self, message: Message) -> Task<Message> {
    match message {
// ..
    Message::ListAllUsers => {
                println!("Request ListAllUsers");
                Task::perform(
                    // We need to first get a reference to the T inside the
                    // Option, and then unwrap it. We use the Arc::clone then
                    // to create a new reference to pgpool
                    get_all_users(Arc::clone(self.pgpool.as_ref().unwrap())),
                    Message::ListAllUsersResult,
                )
            }
    Message::ListAllUsersResult(result) => {
                if let Ok(result) = result {
                    self.all_users = Some(result);
                } else {
                    println!("We couldn't process the result of the Vec<User> ");
                }
                Task::none()
            }
// ...
}

And finally in the fn view I try I first create a Vec,

so I can use Column::from_vec to construct a column with the rows

        fn view(&self) -> Element<Message> {
        // There is a button in my code to call the Message::ListAllUsers
        // ..
        button("Get All Users").on_press(Message::ListAllUsers),
        // ...
        // We start with an empty vector of Type Element, which is
        // the lowest form of a widget, we should be able to push
        // widget::row's into it.
        let mut all_users_vec: Vec<Element<Message>> = Vec::new();
        if self.all_users.is_some() {
            for user in self.all_users.as_ref().unwrap().iter() {
                all_users_vec.push(
                    row![
                        text(&user.first_name),
                        text(&user.last_name),
                        text(&user.telephone_number),
                        text(&user.email_address)
                    ]
                    .into(),
                );
            }
        }
        // We now need to publish it.
        // then we can use the from_vec function on the column of rows
        // to build an iced element to show on the screen
        let all_users_component = Column::from_vec(all_users_vec);

        column![form, all_users_component].into()
        }

This the async function for getting the rows

This should work. So I do get the correct data here.


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);
        }
    }
    Ok(users)
}

Help would be greatly appreciated. I am learning Iced to build something cool, but this is a hurdle for the time being.

Thanks in advance,
Alex

The error was not with my Iced view part, but with my while loop. Now it’s fixed.

The flag for deleting a post doesn’t work. But if a moderator sees this, it can be removed, as it is not relevant to the iced discourse. Thanks!

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)
}