Skip to content

Instantly share code, notes, and snippets.

@rebo
Created July 23, 2020 20:10
Show Gist options
  • Save rebo/8d1f84036c84d14fef28d645c6478869 to your computer and use it in GitHub Desktop.
Save rebo/8d1f84036c84d14fef28d645c6478869 to your computer and use it in GitHub Desktop.
pub fn view() -> Node<Msg> {
let next_id = loaded_users_ids().get().len() + 1;
Column![
Item![
align = ColumnAlign::TopCenter,
h1!["Multi Fetch Example"],
],
Item![
align = ColumnAlign::TopCenter,
fancy_button!["Load Next User",
mouse_ev(Ev::Click, move |_|
{
loadable_user(next_id as u32).update(|u| *u = Loadable::Request(next_id.to_string()));
loaded_users_ids().update(|l| l.push(next_id as u32));
}
)
]
],
Item![
align = ColumnAlign::TopCenter,
div![
loaded_users_ids().get().iter().rev().map(|id|
user_view(*id).get()
),
],
],
]
}
#[derive(Deserialize, Debug,Clone)]
pub struct User {
id: u32,
email: String,
name:String,
phone:String,
}
#[atom]
fn loaded_users_ids() -> Atom<Vec<u32>> {
vec![]
}
#[derive(Clone)]
pub enum Loadable<T> {
NotRequestedYet,
Loading,
Request(String),
Loaded(T),
Error(String),
}
#[atom]
fn loadable_user( id: u32) -> Atom<Loadable<User>> {
Loadable::NotRequestedYet
}
#[reaction]
fn username(id: u32)-> Reaction<Loadable<User>>{
let loading_user = loadable_user(id).observe();
if let Loadable::Request(user_id) = &loading_user {
loadable_user(id).update(|u| *u = Loadable::Loading);
spawn_local({
let user_id = user_id.clone();
async move {
let user_name = format!("https://jsonplaceholder.typicode.com/users/{}",user_id);
let response = fetch(&user_name).await.expect("HTTP request failed");
match response.check_status(){
Ok(response) => {
let user = response
.json::<User>()
.await
.expect("deserialization failed");
loadable_user(id).update(|u| *u = Loadable::Loaded(user));
},
Err(_error) => {
loadable_user(id).update(|u| *u = Loadable::Error("Network connection error!".to_string()));
}
}
my_app().get_with(|app| if let Some(app)=app{app.update(Msg::NoOp)});
}
});
}
loading_user
}
#[reaction]
fn user_view(id: u32) -> Reaction<Node<Msg>> {
match username(id).observe(){
Loadable::NotRequestedYet => {
div!["Not Requested A User Yet"]
},
Loadable::Loading => {
div!["Loading"]
},
Loadable::Request(_user_id) => {
div!["Loading",]
},
Loadable::Loaded(user) => {
div![s().m(px(4)).px(px(24)).py(px(12)).radius(px(4)).bg_color("#BBB"),
s().style_child("p").m(px(4)).py(px(8)).px(px(6)),
p!["Name: ", user.name],
p!["Id: ", user.id],
p!["Email: ", user.email],
]
}
Loadable::Error(err) => {
div!["There was an error with loading the user: ", err]
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment