Reputation: 182
I want to be able to pass user meta data through the :meta
map in phoenix presence to access it from the JavaScript side. More specifically, I want to be able to push image file paths (strings) and have them associated with each user in my presence list. The documentation gives this example for overriding the fetch/2 function to add User model data into the :meta
map:
def fetch(_topic, entries) do
query =
from u in User,
where: u.id in ^Map.keys(entries),
select: {u.id, u}
users = query |> Repo.all |> Enum.into(%{})
for {key, %{metas: metas}} <- entries, into: %{} do
{key, %{metas: metas, user: users[key]}}
end
end
However, when I make the appropriate changes for my User Model, I get errors regarding the variable u and the from/2 function as well as cannot use ^Map.keys(entries) outside of match clauses
.
I went looking for examples of people trying to do similar things and was unable to find anything on github that is similar to what I am attempting here.
Anyone have any idea how I can go about restructuring the fetch/2 function so that it will work properly? I have a basic user model with 3 fields, email, password, and icon/avatar image.
Upvotes: 2
Views: 381
Reputation: 182
I found out what my problem is. Basically, the metas
map in my application is not always populated with the value that I want it to be. In this case, it doesn't always have the user.id
inside of it. Apparently, when a user joins the channel, the fetch function is called at least 4 times. If I inspect the fetch function's entries map
after running Map.keys
on it, it returns:
["1"]
["1"]
[]
[]
So basically in two out of the four instances where the fetch function is being called, my channel app is returning 2 empty values for the key and when those empty values are put into the query it causes an error.
Unfortunately, this means that there is an error some where else in the application that causes this empty value to be passed to my fetch function; most likely in the JavaScript or my channel modules.
I'm going to have to rebuild this app from scratch, so I guess that means this question is closed. Alternatively, I could put in some error handling in the form of a guard or pattern matching statement to protect against these empty values, but I think it would be better in the long run if I just restart.
Upvotes: 1
Reputation: 4507
You need to import Ecto.Query
to use the from
macro. This is done in your web.ex
file so when you use MyApp.Web, :controller
, you have it imported through the quote
block in web.ex
. However, you need to do this manually in other modules.
Add the following to the top of your presence module like this
defmodule MyApp.Presence do
use Phoenix.Presence, otp_app: :my_app,
pubsub_server: MyApp.PubSub
import Ecto.Query
# ...
end
Upvotes: 0