Building signals
As established, Sea.Signal.emit/1
takes your signal struct and emits it to defined observers.
%InvoiceCreatedSignal{invoice_number: "2019/1"}
|> Sea.Signal.emit()
In practice, you’ll often want to convert more complex data structures into signal payload -
properly documented and decoupled from original context. In such cases, the signal module serves as
a fitting place for placing such conversion. Let’s place it in build
function like below:
defmodule InvoiceCreatedSignal do
use Sea.Signal
emit_to AnalyticsObserver
defstruct [:invoice_number]
def build(%Invoice{invoice_number: invoice_number}) do
%__MODULE__{
invoice_number: invoice_number
}
end
end
And so you would emit the signal as follows:
invoice
|> InvoiceCreatedSignal.build()
|> Sea.Signal.emit()
Now however, assuming that the function which builds the signal struct from arbitrary data is indeed
named build
(ie. it implements the Sea.Signal.build/1
callback), you may simplify the signal
build-and-emission code to just a single function call:
InvoiceCreatedSignal.emit(invoice)
It may look like one line less, but single signal may be emitted from multiple places & multiple
input data structures in more complex applications plus the point of abstracting away side-effects
was to make things clearer so the Sea.Signal.emit/1
convenience may make a significant
difference.