MVCoconut / coconut.ui

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

default @:attribute not working as before #49

Closed AdrianV closed 4 years ago

AdrianV commented 4 years ago

I used to have something like this, that worked before the last change 2922be9a1edfe8ae9a5378523ed3801a91aaee5c

class MyButton extends View {
    @:attribute var title: String;
    @:attribute var click: Void->Void;
    @:attribute var child: Void->RenderResult = emptyChild;

    function emptyChild()
        return <span></span>;

    function render() {
        return
            <a href="#" 
                class="button button-outline" 
                onclick={click}
            >{title}
            {child()}
            </a>;
    }
}

now I get an error "TypeError: tink_state_Observable.get_value(...) is not a function" in:

        ,child: function() {
        return (tink_state_Observable.get_value(this.__coco_child))();
    }

looks like __coco_child is initialized with something weird

back2dos commented 4 years ago

Hmm. I struggle to reproduce this. I added a test and it passes.

I also added a potential fix, but it's hard to tell, because the test passes with it and without it.

Could you please confirm it works for you too?

Otherwise, I'd need the exact dependencies, params and haxe versions. Or if you can make the test fail, that would be even better ;)

AdrianV commented 4 years ago

Sorry I was a bit lazy and didn't test if my example will show the problem. To reproduce it, I needed to wrap the view into another view like I did in my app:

I compiled it with a recent haxe 4.1 to coconut.vdom, all libs from git.

class Test {
    static inline function mount(o) {
        var wrapper = document.createElement('wrapper-element');
        document.body.appendChild(wrapper);
        coconut.ui.Renderer.mount(wrapper, o);
    }

    static function main() {
        var data = [{title: "test", click: () -> trace("yo")}];
        mount(hxx('<Buttons buttons={data} />'));
    }
}

typedef ButtonInfo = {
    title:String,
    click:Void->Void,
    ? child:Void->RenderResult
}

class Buttons extends View {
    @:skipCheck
    @:attribute var buttons:Array<ButtonInfo>;

    function render() {
        return
        <div>
            <for {b in buttons}>
                <MyButton {...b} />
            </for>
        </div>;
    }

}

class MyButton extends View {
    @:attribute var title:String;
    @:attribute var click:Void->Void;
    @:attribute var child:Void->RenderResult = emptyChild;

    function emptyChild()
        '<span>DEFAULT</span>';

    function render()
        '
    <a href="#"
      class="button button-outline"
      onclick={click}
    >
      {title}
      {child()}
    </a>
  ';
}

test.zip

AdrianV commented 4 years ago

many thanks - working again.