MVCoconut / coconut.ui

Wow, such reactive view! Much awesome!
The Unlicense
89 stars 9 forks source link

@:loaded not working with hxnodejs #92

Closed grepsuzette closed 2 years ago

grepsuzette commented 2 years ago

Suggesting to have something like warning: -lib hxnodejs is used with coconut, it may create problems with a #if hxnodejs somewhere. At least for me, whenever hxnodejs is used, then asynchronous @:loaded cause no change (the Promised computed or within views stays on Loading, even though the promise triggers something).

This can especially be painful for quick tests or prototypes, in my case I reused a T.hx and forgot a -lib hxnodejs in the hxml and from there on started to doubt everything. IIRC it is not even the first time ;)

So I propose this beginner-friendly warning, for my sake and the sake of others.

back2dos commented 2 years ago

It would be better to understand why @:loaded stops working. If someone wants to create an app with node-webkit or electron, things shouldn't just silently fall apart.

grepsuzette commented 2 years ago

Then I will rename this issue. BTW my test is using -lib coconut.vdom, not react. Haxe 4.2.4, all other libs installed with lix +coco data.

grepsuzette commented 2 years ago

For the test I use something like:

import coconut.Ui;
import coconut.Ui.hxx;
import coconut.ui.*;
import tink.pure.List;
using tink.state.Promised;
using tink.CoreApi;

class M implements coconut.data.Model {

    @:loaded var inventory : List<String> = {
        var trig = Promise.trigger();
        Future.delay( 1000, function() {
            untyped console.log('triggering now');
            trig.trigger(Success(List.fromArray( ['milk', 'beer', 'brandy'] )) );
        });
        trig;
    }
}

class V extends View {
    @:attr var m: M;
    function render() <> 
        <h2>Public guild inventory</h2>
        <ul>
        <switch {m.inventory}>
            <case {Done(list)}>
                <for {e in list}><li>{e}</li></for>
            <case {Loading}>
                Wait...
            <case {Failed(e)}>
                oohoh
        </switch>
        </ul>
    </>;
}

class T {
    static function main() {
        var doc = js.Browser.document;
        var div = doc.createDivElement();
        js.Browser.document.body.appendChild( div);
        var m = new M();
        Renderer.mount( div, hxx('<V m={m} />'));
    }
}

hxml file:

--js t.js
-lib tink_core
-lib tink_pure
-lib coconut.ui
-lib coconut.data
-lib coconut.vdom
-main T.hx
# the culprit:?
-lib hxnodejs

The probably useless index.html

<!doctype html>
<html>
<head></head>
<body>
  hello world
  <script src="t.js"></script>
</body>
</html>

For me, having -lib hxnodejs makes the view stay on "Wait...", but without it lists the beverages.

Edit: bug reproduced again with a fresh new test

kevinresol commented 2 years ago

Is this https://github.com/haxetink/tink_state/issues/76 ?

grepsuzette commented 2 years ago

Smells like it could be something like this! The reason why I did this test is because my app seems to have has similar problems with @:loaded but only sometimes (I reckon it's when I'm using @:computed on top of a @:loaded, as in computing a List<String> from a Promised<List<Pair<String, T>>>, so having a switch/case over the Promised, it looks like there the observable magic is not working). And my app doesn't use hxnodejs. I don't know exactly if it stopped working because of my code or not, but maybe it's something to do with tink_state.

Edit: trying now to see how to use the fixed version

kevinresol commented 2 years ago

you can update tink_state with lix +tink state --flat

grepsuzette commented 2 years ago

I think I can close this one