go-app: app.Range.Slice bug?

This a simple overlay compoent demo. Click the new button four times, and then click close1 and close2. You will find that close3 and close4 have become close4 and close4.

package overlay

import (
	"fmt"
	"github.com/maxence-charriere/go-app/v9/pkg/app"
)

func Demo() app.UI {
	return &demo{}
}

type (
	demo struct {
		app.Compo
		overlay overlay
		id      int
	}
)

func (this *demo) Render() app.UI {
	return app.Div().
		Body(
			&this.overlay,
			app.Button().
				Text("New").
				OnClick(
					func(ctx app.Context, e app.Event) {
						var close func()
						this.id++
						close = this.overlay.
							Append(
								&dialog{
									FTitle: fmt.Sprintf("Close %d", this.id),
									FOnClose: func(ctx app.Context, e app.Event) {
										close()
									},
								})

					}),
		)
}

------------------------------
package overlay

import (
	"github.com/maxence-charriere/go-app/v9/pkg/app"
	"golang.org/x/exp/slices"
)

type (
	overlay struct {
		app.Compo
		items []app.UI
	}
)

func (this *overlay) Append(ui app.UI) (close func()) {
	this.items = append(this.items, ui)
	if this.Mounted() {
		this.Update()
	}
	return this.closer(ui)
}

func (this *overlay) closer(ui app.UI) func() {
	return func() {
		if i := slices.IndexFunc(this.items, func(item app.UI) bool {
			return ui == item
		}); i > -1 {
			this.items = slices.Delete(this.items, i, i+1)
		}
	}
}

func (this *overlay) Render() app.UI {
	return app.Div().
		Body(
			app.Range(this.items).Slice(func(i int) app.UI {
				return this.items[i]
			}),
		)
}
------------------------------------------
package overlay

import (
	"github.com/maxence-charriere/go-app/v9/pkg/app"
)

type (
	dialog struct {
		app.Compo
		FTitle   string
		FOnClose app.EventHandler
		key      interface{}
	}
)

func (this *dialog) OnInit() {
	this.key = this
}

func (this *dialog) Render() app.UI {
	return app.Div().
		Body(
			app.Div().
				Body(
					app.Button().
						Text(this.FTitle).
						OnClick(this.FOnClose, this.key),
				),
		)
}

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 15 (6 by maintainers)

Most upvoted comments

Not very helpful here but I also regularly get call to released function in every version without any explanation what’s wrong. Most of the time it happens when working with slices that hold component state. Maybe we can detect when it happens and add some error handling?

wasm_exec.js:349 call to released function
syscall/js.valueCall @ wasm_exec.js:349
$syscall_js.valueCall @ 045ed6de:0x19ff9b
$syscall_js.Value.Call @ 045ed6de:0x19d470
$syscall_js.handleEvent @ 045ed6de:0x199c28
$runtime.handleEvent @ 045ed6de:0x21263
$wasm_export_resume @ 045ed6de:0xf1885
_resume @ wasm_exec.js:538
(anonymous) @ wasm_exec.js:549