Created
July 23, 2020 20:10
-
-
Save rebo/8d1f84036c84d14fef28d645c6478869 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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