Build your first Popcorn application
View SourceYou will build a supervised counter. JavaScript will call its GenServer and show the returned value.
Complete Installation before this tutorial.
Create the counter
Create lib/my_app/counter.ex:
defmodule MyApp.Counter do
use GenServer
def start_link(_opts) do
GenServer.start_link(__MODULE__, 0, name: :counter)
end
@impl true
def init(count), do: {:ok, count}
@impl true
def handle_call(["add", amount], _from, count) do
count = count + amount
{:reply, count, count}
end
endThe process owns the count. Its registered name lets JavaScript address it. JavaScript arrays become BEAM lists, so the callback matches a list.
Add the bridge to the supervision tree
Update lib/my_app/application.ex:
defmodule MyApp.Application do
use Application
@impl true
def start(_type, _args) do
children = [
Popcorn.Proxy,
MyApp.Counter
]
Supervisor.start_link(children,
strategy: :one_for_one,
name: MyApp.Supervisor
)
end
endPopcorn.Proxy connects JavaScript calls and casts to GenServers. A plain
send() does not use the proxy.
Compile the application again:
mix compile
Call the counter
Add this code after Popcorn.init() in the JavaScript entry point:
const reply = await popcorn.genserver.call("counter", ["add", 2]);
if (!reply.ok) throw reply.error;
document.querySelector("#count").textContent = String(reply.data);Add the target element to the page:
<p>Count: <span id="count">0</span></p>Start the Vite development server. The page shows Count: 2 after Popcorn
starts.
What happened
Vite packaged the application and its dependencies as browser assets. Popcorn started the OTP application inside a Web Worker.
JavaScript sent a normal GenServer call through Popcorn.Proxy. The counter
updated its state and returned the new value.
Next, read Send messages and use GenServers.