Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

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

Inline async ajax calls (and child querying) #636

Closed
Boscop opened this issue Sep 6, 2019 · 6 comments
Closed

Inline async ajax calls (and child querying) #636

Boscop opened this issue Sep 6, 2019 · 6 comments
Labels

Comments

@Boscop
Copy link

Boscop commented Sep 6, 2019

Are there any plans to allow inline async ajax calls and child querying, without going through another update call?
Similar as PureScript/Halogen allows.

@Boscop
Copy link
Author

Boscop commented Sep 22, 2019

We could take some inspiration from this:
https://github.com/carlosdp/plaster
To make yew more async, similar to purescript-halogen.

@jstarry
Copy link
Member

jstarry commented Sep 27, 2019

Child querying may get solved with #665, cool if we limit this issue to async ajax calls?

Sorry I misunderstood what you meant you meant by child querying earlier. We can keep this as is for discussion.

@Boscop
Copy link
Author

Boscop commented Sep 28, 2019

Ok :)
It's better to keep the issues separate.

@hgzimmerman
Copy link
Member

hgzimmerman commented Nov 11, 2019

Hey, @Boscop, now that minimal futures support exists, lets explore this idea more.

So is what you are proposing effectively like:

let future_callback = FutureCallback::new(scope, |this: &mut Self, _click_event: ClickEvent| {
    this.has_been_clicked = true;
});

html!{
    <button onclick=future_callback >{"Button"}</button>
}

Add various macro sugar to enable just putting the |_,_| {} inline in the html macro.


Internally, it might be possible to have a future (EDIT: are futures even needed to represent this?), which when it gets an event, takes its given callback and the event and sends them both to the component loop via a scope, which then acquires a mutable reference to the component state, and calls the closure with the state and event/message, mutating the component without ever touching the message passing system/Component::update.

I don't know how event generation might be represented as futures, how this system could coincide with existing Callback infrastructure, and how this would be used within Components.


I'm not so sure about this being easily achievable, or practical in light of what existing design decisions have been made, but is this approximately what you are wanting?

@hgzimmerman
Copy link
Member

hgzimmerman commented Nov 22, 2019

To follow up on this, I think sticking functions to update state inside html! is currently possible, without utilization of async/await.

pub struct State {
    counter: usize
   // ...
}
pub struct Effect(Rc<Fn(&mut State) -> ShouldRender>);
fn effect<F>(f:F) -> Effect where F: Fn(&mut State) -> ShouldRender {...}

//...
fn update(&mut self, msg: Effect) -> ShouldRender {
    (msg.0)(self)
}
fn view(&self) -> Html<State> {
    html!{
        <button onclick=|_| effect(|state| state.counter += 1) ></button>
    }
}

I'm going to try this out in the Yewtil crate, and see if it is possible.
Edit: https://github.com/yewstack/yewtil/pull/30/files#diff-b4e7b5db738bf65d13d090b42255226dR7

@Boscop
Copy link
Author

Boscop commented Feb 11, 2020

@hgzimmerman Sorry for the late response.
"So is what you are proposing effectively like:"
Not what I meant, but that would also be a nice inline feature to have.
What I mean is something like this.
IOW, being able to ask children what their state is, in the parent's update method. Without having to go through view, and especially being able to also update a child's state without re-rendering the parent, ONLY the child (but only if its state changed in such a way that it requires re-rendering).
In the above PureScript example, you could also call SetOn on the child in the same way inline, i.e. not just read-only querying but also setting a child's state.
Currently it's not possible because we have no references to children in the parent.
I've been experimenting with the WeakComponentLink trick but it's too verbose and cumbersome to be a scalable solution for this common pattern/use case.
In my app, the top level component receives WS msgs at 30 FPS and has to update a small part of a child on most frames, but Yew will always re-render the parent when updating the child through view, which means it will re-render the whole app, leading to huge CPU usage (over 100% in chrome task manager, so the app then can't process incoming WS msgs fast enough) and making the app unuseable, if it wasn't for the WeakComponentLink hack that I'm using now, until there's a better way.
More detail here: #350

This is kinda related to the async inline ajax calls by the fact that both are enabled by monads in PureScript's Halogen framework, thus both things are similarly concise.

@yewstack yewstack locked and limited conversation to collaborators Sep 23, 2021
@mc1098 mc1098 closed this as completed Sep 23, 2021

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
Projects
None yet
Development

No branches or pull requests

4 participants