Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fetch support fetch_once() and fetch_later #9

Open
rebo opened this issue Mar 9, 2020 · 1 comment
Open

fetch support fetch_once() and fetch_later #9

rebo opened this issue Mar 9, 2020 · 1 comment

Comments

@rebo
Copy link
Owner

rebo commented Mar 9, 2020

Initial draft of fetch support.

Useful for fetching on component mount, or in response to an Event.

fetch_once fetches once straight away and deserializes to the given type (useful for fetching on mount). It automatically refreshes the view when the response is received.

fetch_later prepares a fetch and but only fetches on do_fetch() being called, useful if a fetch is needed in response to a button click.

Both have optional Msg on response.

Let me know if you have any comment on the API surface. The type parameters are a little busy but this should be able to be reduced in the future.

Simple example:

// fetches a user on mount
#[topo::nested]
fn fetch_on_mount_example() -> Node<Msg> {
    let fetch_user = fetch_once::<User, Model, _, _>("user.json", Msg::default());
    div![fetch_user.fetched_value()]
}

Fuller API login example as below:

// fetches a user on log-in click
#[topo::nested]
fn show_user_later() -> Node<Msg> {
    let fetch_user = fetch_later::<User, _>("user.json");

    if let Some(user) = fetch_user.fetched_value() {
        div![
            "Logged in User: ",
            user.name,
            div![a![
                attrs![At::Href=>"#logout"],
                "Log out",
                mouse_ev(Ev::Click, move |_| {
                    fetch_user.delete();
                    Msg::default()
                })
            ]]
        ]
    } else {
        div![a![
            attrs![At::Href=>"#login"],
            "Log in",
            mouse_ev(Ev::Click, move |_| {
                fetch_user.do_fetch::<Model, Msg, Node<Msg>>(Msg::default());
                Msg::default()
            })
        ]]
    }
}

and on mount:

#[topo::nested]
// fetches a user on mount
fn show_user() -> Node<Msg> {
    let fetch_user = fetch_once::<User, Model, _, _>("user.json", Msg::default());
    if let Some(user) = fetch_user.fetched_value() {
        div![
            "Logged in User: ",
            user.name,
            div![a![
                attrs![At::Href=>"#logout"],
                "Log out",
                mouse_ev(Ev::Click, move |_| {
                    fetch_user.delete();
                    Msg::default()
                })
            ]]
        ]
    } else {
        div![a![attrs![At::Href=>"#login"], "Log in"]]
    }
}
@MartinKavik
Copy link
Contributor

I'm a simple user. I don't want to learn and remember fetch_once, fetch_later, .fetched_value, .delete(), do_fetch(, etc. Can I just reuse basic API and write something like:

#[topo::nested]
fn fetch_on_mount_example() -> Node<Msg> {
    let fetched_user = use_state(Option::<User>::default);
    do_once(async || {
        fetched_user.set(fetch("user.json").await.unwrap().json().await.ok()); // PR 353
    });
    div![fetched_user.map(|user| user.name)]
}
#[topo::nested]
fn show_user() -> Node<Msg> {
    let fetched_user = use_state(Option::<User>::default);
    div![
        div![
            "Load user",
            ev(Ev::Click, async || {
                fetched_user.set(fetch("user.json").await.unwrap().json().await.ok()); // PR 353
            } 
        ],
        fetched_user.map(|user| user.name),
    ]
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants