diff --git a/gomponents.go b/gomponents.go index 7b73a3b..ae7cadc 100644 --- a/gomponents.go +++ b/gomponents.go @@ -254,9 +254,20 @@ func Group(children []Node) Node { // If condition is true, return the given Node. Otherwise, return nil. // This helper function is good for inlining elements conditionally. +// If your condition and node involve a nilable variable, use iff because +// go will evaluate the node regardless of the condition. func If(condition bool, n Node) Node { if condition { return n } return nil } + +// Iff execute the function f if condition is true, otherwise return nil. +// it is the preferred way to conditionally render a node if the node involves a nilable variable. +func Iff(condition bool, f func() Node) Node { + if condition { + return f() + } + return nil +} diff --git a/gomponents_test.go b/gomponents_test.go index 32304f3..df5da4f 100644 --- a/gomponents_test.go +++ b/gomponents_test.go @@ -284,3 +284,32 @@ func ExampleIf() { _ = e.Render(os.Stdout) // Output:
You lost your hat!
} + +func TestIff(t *testing.T) { + t.Run("returns node if condition is true", func(t *testing.T) { + n := g.El("div", g.Iff(true, func() g.Node { + return g.El("span") + })) + assert.Equal(t, "
", n) + }) + + t.Run("returns nil if condition is false", func(t *testing.T) { + n := g.El("div", g.Iff(false, func() g.Node { + return g.El("span") + })) + assert.Equal(t, "
", n) + }) +} + +func ExampleIff() { + var nillableVariable *struct { + str string + } + e := g.El("div", + g.Iff(nillableVariable != nil, func() g.Node { + return g.Text(nillableVariable.str) + }), + ) + _ = e.Render(os.Stdout) + // Output:
+}