hey so im playing around with phoenix and built an app that is displaying the current hours, minutes and seconds
timer
defmodule Timr.Ticker do
alias Phoenix.PubSub
@interval 1000
@channel "time:updates"
def init() do
schedule_tick()
{:ok, :timer.tc()}
end
defp schedule_tick do
Process.send_after(self(), :tick, @interval)
end
def current_time do
now = Time.utc_now()
%{hours: now.hour, minutes: now.minute, seconds: now.second}
end
def handle_info(:tick, state) do
time = current_time()
PubSub.broadcast(Timr.PubSub, @channel, "time_update", time)
schedule_tick()
{:noreply, state}
end
end
controller
defmodule TimrWeb.PageController do
use TimrWeb, :controller
alias Timr.Ticker
alias Phoenix.PubSub
def index(conn, _params) do
time = Ticker.current_time()
render(conn, "index.html", time: time)
end
end
html
<h1>Hello World</h1>
<div id="time">
<p>Hours: <span id="hours"><%= @time.hours %></span></p>
<p>Minutes: <span id="minutes"><%= @time.minutes %></span></p>
<p>Seconds: <span id="seconds"><%= @time.seconds %></span></p>
</div>
js
const socket = new Phoenix.Socket("/socket", {params: {token: window.userToken}});
socket.connect();
// Subscribe to the "time:updates" channel
const channel = socket.channel("time:updates", {});
channel.join()
.receive("ok", resp => { console.log("Joined successfully", resp) })
.receive("error", resp => { console.log("Unable to join", resp) });
// Update the time displayed on the page when a "time_update" message is received
channel.on("time_update", data => {
document.getElementById("hours").textContent = data.hours;
document.getElementById("minutes").textContent = data.minutes;
document.getElementById("seconds").textContent = data.seconds;
});
and what I want to do, is to implement a pubsub that is updating the time every second, so you dont have to refresh every damn second. I’ve been playing around with everything for almost 2h and decided to ask for help now