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 core/wasm (import . "github.com/gothicframework/core/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/gothicframework/core/wasm"

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

	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 does two things — it reads the value and registers the current Observe callback as a subscriber, so that callback re-runs whenever the value changes. A plain observable created with CreateObservable exposes exactly two methods: Get and Set.

Important: if you ever need to read a shared value without subscribing to it, that non-tracking read is called Peek — and it lives on a Topic's ObservableField, not on a plain observable. You'll meet it on the Topics page.

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