Phoenix get PubSub to update time

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

What you’ve shown looks reasonable, but where does your application start a Timr.Ticker process?

1 Like

I have that in my application.ex file