dwyl / phoenix-liveview-todo-list-tutorial

✅ Beginners tutorial building a Realtime Todo List in Phoenix 1.6.10 + LiveView 0.17.10 ⚡️ Feedback very welcome!
https://liveview-todo.herokuapp.com/
69 stars 11 forks source link

Something wrong in readme.md #23

Closed huheng233 closed 2 years ago

huheng233 commented 2 years ago

The part of the page_live.ex file described in the readme.md lacks the handle_info method

SimonLab commented 2 years ago

The handle_info function is used to catch any new items added to the list by other client. When a new item is created the broadcast_from callback is called with the socket.assigns passed as the message:

  def handle_event("create", %{"text" => text}, socket) do
    Item.create_item(%{text: text})
    socket = assign(socket, items: Item.list_items(), active: %Item{})
    LiveViewTodoWeb.Endpoint.broadcast_from(self(), @topic, "update", socket.assigns) # This will trigger the handle_info callback
    {:noreply, socket}
  end

The handle_info make sure to update the new list of items and display it on the page:

  def handle_info(data, socket) do
    {:noreply, assign(socket, items: data.payload.items)}
  end

Here the data parameter looks similar to:

%Phoenix.Socket.Broadcast{
  event: "update",
  payload: %{
    __changed__: %{active: true, items: true},
    active: %LiveViewTodo.Item{
      __meta__: #Ecto.Schema.Metadata<:built, "items">,
      id: nil,
      inserted_at: nil,
      person_id: nil,
      status: 0,
      text: nil,
      updated_at: nil
    },
    flash: %{},
    items: [
      %LiveViewTodo.Item{
        __meta__: #Ecto.Schema.Metadata<:loaded, "items">,
        id: 1,
        inserted_at: ~N[2021-12-01 11:42:10],
        person_id: nil,
        status: 0,
        text: "item 1",
        updated_at: ~N[2021-12-01 11:42:10]
      }
    ],
    live_action: nil
  },
  topic: "live"
}
SimonLab commented 2 years ago

Now we now the structure of the message, we can use pattern matching in the handle_info parameter and make sure the correct message format is received:

def handle_info(%{event: "update", payload: %{items: items}}, socket) do
  {:noreply, assign(socket, items: items)}
end                                                                                                                                                                                  
SimonLab commented 2 years ago

Hi @huheng233 thanks for opening this issue. The Readme should be now updated with the handle_info section. Let us know if this works for you, Thanks