Commands are how you perform I/O in Bubble Tea. They're functions that return a tea.Msg and run asynchronously.
A tea.Cmd is a function that performs I/O and returns a tea.Msg:
type Cmd func() Msg
Commands are never run directly by you. Instead, you return them from Init or Update, and the Bubble Tea runtime executes them.
Here's a command that makes an HTTP request:
func checkServer() tea.Msg {
res, err := http.Get("https://api.example.com/status")
if err != nil {
return errMsg{err}
}
defer res.Body.Close()
return statusMsg(res.StatusCode)
}
Return it from Update:
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyPressMsg:
if msg.String() == "c" {
return m, checkServer // Run the command
}
case statusMsg:
m.status = int(msg)
return m, nil
case errMsg:
m.err = msg.err
return m, nil
}
return m, nil
}
Bubble Tea provides several useful commands:
Exits the program:
return m, tea.Quit
Run multiple commands at once:
return m, tea.Batch(
checkServer,
startTimer,
loadData,
)
Run commands in order, waiting for each to complete:
return m, tea.Sequence(
authenticate,
loadUserData,
fetchMessages,
)
Use tea.Tick for periodic updates:
type tickMsg time.Time
func tickEvery() tea.Cmd {
return tea.Tick(time.Second, func(t time.Time) tea.Msg {
return tickMsg(t)
})
}
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg.(type) {
case tickMsg:
m.time = time.Now()
return m, tickEvery() // Schedule next tick
}
return m, nil
}
Create commands that take parameters:
func fetchUser(id int) tea.Cmd {
return func() tea.Msg {
user, err := api.GetUser(id)
if err != nil {
return errMsg{err}
}
return userMsg{user}
}
}
// Use it:
return m, fetchUser(42)
type model struct {
loading bool
data []string
err error
}
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyPressMsg:
if msg.String() == "r" {
m.loading = true
return m, fetchData
}
case dataMsg:
m.loading = false
m.data = msg.data
case errMsg:
m.loading = false
m.err = msg.err
}
return m, nil
}
type debounceMsg struct{}
func debounce(d time.Duration) tea.Cmd {
return tea.Tick(d, func(time.Time) tea.Msg {
return debounceMsg{}
})
}