How to show delete status message html page after deleting a record

phoenix
troubleshooting
#1

Hi,
I’m trying to display a “Deletion was successful” status page after deleting a record.
The deletion is initiated with a javascript function on the client side (show below):

async function deleteStudent(event) {
  try {
    let studentID = event.target.dataset.studentid
    console.log(studentID)
    let result = await fetch(`/students/${studentID}`, {method: 'delete'})
    console.log(result)
  } catch (error) {
    console.log(`ERROR: Unable to delete student`)
  }
}

On the server side, I have the controller to handle the delete student request:

  def delete(conn, %{"id" => id}) do
    {id, _} = Integer.parse(id)
    Tutor.delete_student(id)
    conn
    |> IO.inspect
    |> render("showdelete.html", student_id: id)
  end

and in the file tutor.ex file (this function is working fine):

  def delete_student(id) do
    multi = Multi.new
    |> Multi.run(:sponsorstudent, fn repo, changes ->
      # delete student's relationship with sponsors
       from(ss in "sponsors_students", where: ss.student_id == ^id)
       |> repo.delete_all
       |> case do
        {records_count, response} -> {:ok, records_count}
        {:error, _} -> {:error, nil}
        end
       end)
    |> Multi.run(:student, fn repo, changes ->
      # delete student
      from(s in "students", where: s.id == ^id)
      |> repo.delete_all
      |> case do
        {records_count, response} -> {:ok, records_count}
        {:error, _} -> {:error, nil}
        end
      end)

    case Repo.transaction(multi) do
      {:ok, _} -> 
        IO.puts("deleted student") 
        {:ok, id}
      {:error, operation, response, _} -> {:error, "#{operation} failed - #{response}"}
    end
  end

However, the page “showdelete.html” is not displayed at the client side. This is the log I’m seeing on the server:

[info] DELETE /students/45
[debug] Processing with TutorWeb.StudentController.delete/2
  Parameters: %{"id" => "45"}
  Pipelines: [:browser]
[debug] QUERY OK db=1.2ms
begin []
[debug] QUERY OK source="sponsors_students" db=1.2ms
DELETE FROM "sponsors_students" AS s0 WHERE (s0."student_id" = $1) [45]
[debug] QUERY OK source="students" db=0.7ms
DELETE FROM "students" AS s0 WHERE (s0."id" = $1) [45]
deleted student
[debug] QUERY OK db=0.1ms
commit []
%Plug.Conn{
  adapter: {Plug.Cowboy.Conn, :...},
  assigns: %{},
  before_send: [#Function<2.131575234/1 in Phoenix.Controller.fetch_flash/2>,
   #Function<0.58261320/1 in Plug.Session.before_send/2>,
   #Function<1.112466771/1 in Plug.Logger.call/2>,
   #Function<0.6186620/1 in Phoenix.LiveReloader.before_send_inject_reloader/2>],
  body_params: %{},
  cookies: %{},
  halted: false,
  host: "0.0.0.0",
  method: "DELETE",
  owner: #PID<0.436.0>,
  params: %{"id" => "45"},
  path_info: ["students", "45"],
  path_params: %{"id" => "45"},
  port: 4000,
  private: %{
    TutorWeb.Router => {[], %{}},
    :phoenix_action => :delete,
    :phoenix_controller => TutorWeb.StudentController,
    :phoenix_endpoint => TutorWeb.Endpoint,
    :phoenix_flash => %{},
    :phoenix_format => "html",
    :phoenix_layout => {TutorWeb.LayoutView, :app},
    :phoenix_pipelines => [:browser],
    :phoenix_router => TutorWeb.Router,
    :phoenix_view => TutorWeb.StudentView,
    :plug_session => %{},
    :plug_session_fetch => :done
  },
  query_params: %{},
  query_string: "",
  remote_ip: {127, 0, 0, 1},
  req_cookies: %{},
  req_headers: [
    {"accept", "*/*"},
    {"accept-encoding", "gzip, deflate"},
    {"accept-language", "en,ms;q=0.9"},
    {"connection", "keep-alive"},
    {"host", "0.0.0.0:4000"},
    {"origin", "http://0.0.0.0:4000"},
    {"referer", "http://0.0.0.0:4000/students"},
    {"user-agent",
     "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"}
  ],
  request_path: "/students/45",
  resp_body: nil,
  resp_cookies: %{},
  resp_headers: [
    {"cache-control", "max-age=0, private, must-revalidate"},
    {"x-request-id", "FZ1HngLKl5pMvh0AAAah"}
  ],
  scheme: :http,
  script_name: [],
  secret_key_base: :...,
  state: :unset,
  status: nil
}
[info] Sent 200 in 73ms

I’m not sure whether this has anything to do with the server code or at the client side. I would greatly appreciate any pointers/help with this.
Kind regards.

#2

Hi @rameshkumar! It seems that rather than navigating to the delete route in the browser you’re using the fetch Javascript function to make a request to the route without changing the page. Because of this instead of rendering the page the HTML is stored inside the request variable, so you’ll need to add more Javascript if you want to render it to the page from here.

Alternatively you can remove the Javascript and instead create a HTML link to the route using Phoenix’s link function and specifying the delete method. https://hexdocs.pm/phoenix_html/Phoenix.HTML.Link.html#link/2

2 Likes
#3

Thank you so much. :pray:
I didn’t realize using the ‘fetch’ call does not automatically make the browser render the new page.

1 Like
#4

With fetch() you get the response object as a Promise in the javascript, you can use .then() to work with callback functions to render the page, modify DOM elements, etc.

2 Likes