Skip to content

Conversation

@Gnyblast
Copy link

- Currently there's set,get, delete and observe method for statemanager
- Delete method even though it says halts the observations, it doesn't do it really
- I experienced it on a Rangeloop created component that interacts with confirmation dialog and observe state from there.
- Observation getting created when dialog was opened and I was deleting it on close, but it looks like they keep observing and interacting with multiple component same way was stacking up the obvervations.
- I implemented unobserve method to overcome this and it seems to work.
- This is pretty much `subscribe` and `unsubscribe` in angular.

    - Currently there's set,get, delete and observe method for statemanager
    - Delete method even though it says halts the observations, it doesn't do it really
    - I experienced it on a Rangeloop created component that interacts with confirmation dialog and observe state from there.
    - Observation getting created when dialog was opened and I was deleting it on close, but it looks like they keep observing and interacting with multiple component same way was stacking up the obvervations.
    - I implemented unobserve method to overcome this and it seems to work.
    - This is pretty much `subscribe` and `unsubscribe` in angular.
@maxence-charriere
Copy link
Owner

I what scenario would you need to unobserve a state?

@Gnyblast
Copy link
Author

Gnyblast commented Nov 11, 2025

Sure let me explain,

Let say I have a app-level confirmation dialog. These kind of things are generally injected only once to app and used ad-hoc.

So, imagine I have components that are generated with app.Range and each component has a button for an action that needs confirmation. So onclick to this button, I open the confirmation dialogs and setup an observeState with onclick, so I start listening what button is clicked in dialog modal through the statemanager. Let's say component X is clicked and opened dialog then set a observation then component Y then component Z. At the end when dialog opened by component Z is clicked, all X,Y,Z has a subscription to that state and gets notified and this might cause all of them to trigger action as each one has been clicked.

So in short, there are states in app-wise that should have only 1 single observers:

confirmation_dialog.go

func (c *ConfirmationDialog) OnMount(ctx app.Context) {
	var dialogState bool
	ctx.ObserveState("confirmation", &dialogState).OnChange(func() {
		if dialogState {
			c.openConfirmation(ctx)
		}
	})
}

func (c *ConfirmationDialog) openConfirmation(ctx app.Context) {
	doc := app.Window().Get("document")
	mdc := app.Window().Get("mdc")
	dialogElem := doc.Call("querySelector", "#confirmDialog")
	dialog := mdc.Get("dialog").Get("MDCDialog").New(dialogElem)
	c.onDialogClosing = app.FuncOf(func(this app.Value, args []app.Value) any {
		reason := args[0].Get("detail").Get("action").String()
		ctx.SetState("confirm_state", reason == "accept")
		dialogElem.Call("removeEventListener", "MDCDialog:closing", c.onDialogClosing)
		return nil
	})
	dialogElem.Call("addEventListener", "MDCDialog:closing", c.onDialogClosing)
	dialog.Call("open")
}

some_component.go

func (p *Pod) deallocate(ctx app.Context, e app.Event) {
	ctx.SetState("confirmation", true)
	var confirmState bool
	ctx.ObserveState("confirm_state", &confirmState).OnChange(func() {
		fmt.Println(confirmState)
		//TODO: Do deallocation
		ctx.UnObserveState("confirm_state")
	})
}

Otherwise it will cause many troubles in the app, and this is not just my idea, I used almost this type of subscriptions in many places especially angular. And all provides unsubscribe method.

@Gnyblast
Copy link
Author

@maxence-charriere any idea about this? Can it be achieved some other way?

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

Successfully merging this pull request may close these issues.

2 participants