Update information after deleting in LiveView

I am using Jquery DataTables to improve the table view. The insert or update operations occur without any problem, but when deleting it does not update the table after the refresh.

For example: I have two records and delete only one. In the database it is only with one record but in the listing (table) it shows both, as if nothing happened. Only after a refresh that updates.

{:phoenix_live_view, "~> 0.13.1", override: true},
{:phoenix, "~> 1.5.0-rc.0", override: true},

// app.js

jQuery(document).ready(function($){
  function initDataTable() {
    $("#mytable").DataTable()
  }

  $(document).on("phx:update", initDataTable)
})

index.html.leex

<div class="col-12" phx-update="ignore">
        <table id="mytable" class="table table-sm table-dashboard no-wrap mb-0 fs--1 w-100">
          <thead class="bg-200">
            <tr>
              <th class="sort pr-1 align-middle">ID</th>
              <th class="sort pr-1 align-middle">Inserted at:</th>
              <th class="sort pr-1 align-middle">Updated at:</th>
              <th class="no-sort pr-1 align-middle data-table-row-action">Ações:</th>
            </tr>
          </thead>
          <tbody>
            <%= for empresa <- @empresas do %>
              <tr id="empresa-<%= empresa.id %>" class="btn-reveal-trigger">
                <td class="align-middle"><%= empresa.id %></td>
                <td class="align-middle"><%= empresa.inserted_at %></td>
                <td class="align-middle"><%= empresa.updated_at %></td>
                <td class="align-middle white-space-nowrap">
                  <div class="dropdown text-sans-serif">
                    <button class="btn btn-link text-600 btn-sm dropdown-toggle btn-reveal mr-3" type="button" id="dropdown0" data-toggle="dropdown" data-boundary="html" aria-haspopup="true" aria-expanded="false"><span class="fas fa-ellipsis-h fs--1"></span></button>
                    <div class="dropdown-menu dropdown-menu-right border py-0" aria-labelledby="dropdown0">
                      <div class="bg-white py-2">
                        <%= live_patch "Show", to: Routes.admin_empresa_show_path(@socket, :show, empresa), class: "dropdown-item" %>
                        <%= live_patch "Edit", to: Routes.admin_empresa_new_path(@socket, :edit, empresa), class: "dropdown-item text-warning" %>
                        <%= link "Delete", to: "#", phx_click: "delete", phx_value_id: empresa.id, data: [confirm: "Are you sure?"], class: "dropdown-item text-danger" %>
                      </div>
                    </div>
                  </div>
                </td>
              </tr>
            <% end %>
          </tbody>
        </table>
</div>

index.ex

def handle_event("delete", %{"id" => id}, socket) do
    empresa = Empresa.get_empresa!(id)
    {:ok, _} = Empresa.soft_delete_empresa(empresa)    

    {:noreply,
      socket
      |> put_flash(:info, "Registro excluído com sucesso!")
      |> assign(:empresas, Empresa.list_empresas())
    }
  end

Try change <%= link "Delete", ... to <%= live_patch "Delete", ..., respectively change to route to index page.

Also be careful with a message in put_flash. You can write

def handle_event("delete", %{"id" => id}, socket) do
    empresa = 
       id
       |> Empresa.get_empresa!()
       |> Empresa.soft_delete_empresa()    

    {:noreply,
      socket
      |> show_flash(empresa)
      |> assign(:empresas, Empresa.list_empresas())
    }
end

where

defp show_flash(socket, {:ok, _rv}) do
    put_flash(socket, :info, "Deleting was successful.")
end

defp show_flash(socket, {:error, msg}) do
    put_flash(socket, :error, "#{msg}")
end
1 Like

Return error:

[error] GenServer #PID<0.706.0> terminating
** (UndefinedFunctionError) function AutoplacasWeb.Admin.EmpresaLive.Index.handle_params/3 is undefined or private

sry my mistake, it should be

<div phx-click="delete" 
  phx-value-id=<%= empresa.id %> 
  data: [confirm: "Are you sure?"] 
  class: "dropdown-item text-danger">
</div>

Did not update the list. :frowning:

These updates and inserts, are you doing them in the same view as the table for them to work?

And about the app.js, it does not look like this code is inside a hook, I recommend handling js use inside of one, also, phx-update="ignore" is used to ignore when the content changes, which is happening when you delete something, try removing it.

https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html#module-dom-patching-and-temporary-assigns

When I try to delete the record without “phx-update =” ignore “”, the table loses the “datatable” style and is left with a simple table. But the records are updated normally. The biggest problem is the integration with jquery datatable.

Yeah, I thought so, if you don’t use phx-update="ignore" what happens is that when your DOM updates the js used to mount the table will not execute again, so the table resets to the pure html state.

Have you tried handling the table state with a hook?

https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html#module-js-interop-and-client-controlled-dom

I tried something like this:

let Hooks = {}
Hooks.DataTable = {
  initDataTable() {
    console.log(this.el)
    $(this.el).DataTable({retrieve: true})
  },
  mounted() {
    console.log("MOUNTED")
    this.initDataTable()
  },
  updated(){
    console.log("UPDATED")
    this.initDataTable()
  }
}

It remains in the same situation.