akramic

akramic

Using Elixir as a Presence Client

I’m trying to follow the documentation on using Elixir as a Presence Client as outlined here: [Phoenix.Presence — Phoenix v1.8.8]

Channel join code :

@impl true
  def join("online", params, socket) do
    IO.inspect(params, label: "PARAMS on join")
    send(self(), :after_join)
    {:ok, socket}
  end
  @impl true
  def handle_info(:after_join, socket) do

    IO.inspect(socket)
    user_id = socket.assigns.user
    {:ok, _} = Presence.track(socket, user_id, %{
      user_id: user_id,
      online_at: inspect(System.system_time(:second))
    })
    push(socket, "presence_state", Presence.list(socket))
    {:noreply, socket}
  end



Code for presence.ex



    def init(_opts) do
      {:ok, %{}} # user-land state
    end

    def handle_metas(topic, %{joins: joins, leaves: leaves}, presences, state) do

      IO.inspect(joins, label: "JOINS")
      # fetch existing presence information for the joined users and broadcast the
      # event to all subscribers
      for {user_id, presence} <- joins do
        user_data = %{user: presence.user, metas: Map.fetch!(presences, user_id)}
        msg = {MyApp.PresenceClient, {:join, user_data}}
        Phoenix.PubSub.local_broadcast(MyApp.PubSub, topic, msg)
      end

      # fetch existing presence information for the left users and broadcast the
      # event to all subscribers
      for {user_id, presence} <- leaves do
        IO.inspect(joins, label: "LEAVES")
        metas =
          case Map.fetch(presences, user_id) do
            {:ok, presence_metas} -> presence_metas
            :error -> []
          end

        user_data = %{user: presence.user, metas: metas}
        msg = {MyApp.PresenceClient, {:leave, user_data}}
        Phoenix.PubSub.local_broadcast(MyApp.PubSub, topic, msg)
      end

      {:ok, state}
    end
end

I’m able to join the channel but get the following error:

(KeyError) key :user not found in: %{metas: [%{user: 1, online_at: "1728611576", phx_ref: "F_1DEghkHFXOsARm"}]}

I think that the error is due to this line:

user_data = %{user: presence.user, metas: Map.fetch!(presences, user_id)}

I’d be grateful if someone could point me in the direction of resolving this error.

Many thanks and apologies if this duplicates another post - I couldn’t find anything related to this on the forum.

Most Liked

akramic

akramic

This is called because this line
`

`
should be

 user_data = %{user: user_id, metas: Map.fetch!(presences, user_id)}

and

  user_data = %{user: presence.user, metas: metas}

should be

user_data = %{user: user_id, metas: metas}

I wasn’t looking closely enough at the data structure for presences and presence.

Hope it helps someone.

Where Next?

Popular in Questions Top

nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I forese...
New
PeterCarter
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New

Other popular topics Top

electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 54996 245
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New

We're in Beta

About us Mission Statement