How do I check my notification here?

hi,

I was trying to build the notification using this tutorial here

  1. Created the todo channel
defmodule PgsubWeb.TodoChannel do
  use PgsubWeb, :channel
  alias Pgsub.Pgsub.Todo
  alias Pgsub.Repo

  def join("todo:list", payload, socket) do
    if authorized?(payload) do
      {:ok, socket}
    else
      {:error, %{reason: "unauthorized"}}
    end
  end

  def handle_in("todos", _payload, socket) do
    broadcast_all_to!(socket)

    {:noreply, socket}
  end

  def handle_in("insert", %{"todo" => data}, socket) do
    %Todo{}
    |> Todo.changeset(data)
    |> Repo.insert!

    broadcast_all_to!(socket)

    {:noreply, socket}
  end

  def handle_in("update", %{"todo" => data}, socket) do
    Todo
    |> Repo.get(data["id"])
    |> Todo.changeset(data)
    |> Repo.update!

    broadcast_all_to!(socket)

    {:noreply, socket}
  end

  def handle_in("delete", %{"todo" => data}, socket) do
    Todo
    |> Repo.get(data["id"])
    |> Repo.delete!

    broadcast_all_to!(socket)

    {:noreply, socket}
  end

  defp authorized?(_payload) do
    true
  end

  defp broadcast_all_to!(socket) do
    todos = Todo |> Repo.all
    PgsubWWeb.Endpoint.broadcast!(socket.topic, "todos", %{todos: todos})
  end
end
  1. created the trigger migration for the user
CREATE OR REPLACE FUNCTION notify_todos_changes()
RETURNS trigger AS $$
DECLARE
  current_row RECORD;
BEGIN
  IF (TG_OP = 'INSERT' OR TG_OP = 'UPDATE') THEN
    current_row := NEW;
  ELSE
    current_row := OLD;
  END IF;
  PERFORM pg_notify(
    'todos_changes',
    json_build_object(
      'table', TG_TABLE_NAME,
      'type', TG_OP,
      'id', current_row.id,
      'data', row_to_json(current_row)
    )::text
  );
  RETURN current_row;
END;
$$ LANGUAGE plpgsql;
  1. Creating a genserver to handle the notification
defmodule Pgsub.Notifications do
  use GenServer
  alias Pgsub.{Pgsub.Todo, Repo}

  import Poison, only: [decode!: 1]

  def start_link(channel) do
    GenServer.start_link(__MODULE__, channel)
  end

  def init(channel) do
    {:ok, pid} = Application.get_env(:pgsub, Pgsub.Repo)
      |> Postgrex.Notifications.start_link()
    ref = Postgrex.Notifications.listen!(pid, channel)

    data = Todo |> Repo.all

    {:ok, {pid, ref, channel, data}}
  end

  @topic "todo:list"

  def handle_info({:notification, pid, ref, "todos_changes", payload}, {pid, ref, channel, data}) do
    %{
      "data" => raw,
      "id" => id,
      "table" => "todos",
      "type" => type
    } = decode!(payload)
    row = for {k, v} <- raw, into: %{}, do: {String.to_atom(k), v}
    updated_data = case type do
      "UPDATE" -> Enum.map(data, fn x -> if x.id === id do Map.merge(x, row) else x end end)
      "INSERT" -> data ++ [struct(Todo, row)]
      "DELETE" -> Enum.filter(data,  &(&1.id !== id))
    end

    PgsubWeb.Endpoint.broadcast!(@topic, "todos", %{todos: updated_data})

    {:noreply, {pid, ref, channel, updated_data}}
  end
end

After all this when I’m trying to insert the new user. I’m not getting the notification that I have inserted the new user. Although when I’m trying to insert something else which is not user.

It’s giving me some pid which I don’t know how to get when I’m inserting the user

Last message: {:notification, #PID<0.702.0>, #Reference<0.289176621.289406977.235956>

Can anyone help me here

I’m not completely sure but I think your GenSever needs to subscribe to the topic you are broadcasting to. Try with PgsubWeb.Endpoint.subscribe(@topic)

Still I’m just getting a resource which I’m inserting. not getting any information about the notification. Can you share the subscribe callback ?

handle_in/3 should work, at least that’s how I used it in a project with Channels. This is what I used as a reference: Phoenix.Channel — Phoenix v1.5.8