Gothic Framework G symbol

Observables

An observable is a reactive value. You create one with CreateObservable, read it with Get, and update it with Set. Whenever the value changes, every Observe callback that depends on it re-runs automatically.

If you come from React, this is the equivalent of useState paired with useEffect, but the dependencies are passed explicitly to Observe instead of inferred from a dependency array.

Important: You must dot-import pkg/wasm (import . "github.com/felipegenef/gothicframework/v2/pkg/wasm") for use these helpers, otherwise you will get a tinygo compile error.

Here is the simplest possible example: a counter wired up with one observable and one effect.

import "strconv"
 import . "github.com/felipegenef/gothicframework/v2/pkg/wasm"

 ClientSideState: func() {
	 count := CreateObservable(0)

	 // Re-runs whenever count.Set is called
	 Observe(func() {
		 SetText("counter", strconv.Itoa(count.Get()))
	}, count)

	 CreateWasmFunc("increment", func() {
		 count.Set(count.Get() + 1)
	})
} 

You can pass multiple dependencies to Observe. The callback re-runs whenever any of them changes:

price    := CreateObservable(100)
 quantity := CreateObservable(1)

 // Recomputes whenever price OR quantity changes
 Observe(func() {
	 total := price.Get() * quantity.Get()
	 SetText("total", strconv.Itoa(total))
}, price, quantity) 

Sometimes you need to update several observables at once without firing effects in between. Wrap the writes in BeginBatch and EndBatch, and subscribers will see a single notification at the end:

CreateWasmFunc("reset", func() {
	 BeginBatch()
	 firstName.Set("")
	 lastName.Set("")
	 age.Set(0)
	 EndBatch() // one notification, not three
}) 

Note: Get reads a value and registers the current effect as a subscriber. Peek reads the value without registering. Use Peek inside an Observe callback when you want to read a value but not re-run on its changes.

Important: Always read with Get when the value should drive reactivity, and reserve Peek for the cases where you genuinely want to opt out of tracking. Mixing them up is the most common source of effects that "never re-run" or "re-run too often".

Now that you can model reactive state, let's wire it to the page with DOM helpers like SetText, AddClass, and SetStyle!