问题
Well, I am looking for a good way to pass multiple elements (same column name) that I've retrieved from db into the channels payload.
For example: ppl = Repo.all(People) will return two results with id: 1, name: Mike, id: 2, name: John. The name: (column name) is used for both Mike and John, but when passing through channels payload, I can only pass one map, where can't have both name: John, name: Mike at the same time.
As I understood channels, we use a map(payload) that is send back to the client. I am planning to generate html dynamically, based on the information I got from the db. Therefore need to pass all of the ppl from People in one map/payload.
My current plan is to make something like recursion function that will create maps separately for ppl. %{name1: John} and %{name2: Mike} and then use Map.merge to combine them and path as one map. So, my question: is there a better way to path multiple elements from same table (same column) in the payload? Any suggestions/recommendations appreciated!
Thanks!
回答1:
So, my question: is there a better way to path multiple elements from same table (same column) in the payload?
The documentation says that the payload must be a map, but it can contain anything that's serializable.
Phoenix.Channel.broadcast(socket, event, message)
Broadcast an event to all subscribers of the socket topic.
The event’s message must be a serializable map.
https://hexdocs.pm/phoenix/Phoenix.Channel.html#broadcast/3
So you can just pass a list inside a key in the payload using one of these two approaches:
If you have a Poison.Encoder instance for Person, you can do:
broadcast socket, "people", %{people: Repo.all(Person)}
otherwise, only select the required keys from the query directly into a map, and send that:
people = from(p in Person, select: map(p, [:id, :name])) |> Repo.all
broadcast socket, "people", %{people: people}
and then (in either case) access it as an Array in JS using payload.people.
来源:https://stackoverflow.com/questions/39188718/elixir-phoenix-map-for-the-channels-payload