Push_redirect and push_patch are not causing change to url/liveview

Hello everyone,

I’ve been trying to add a live component to a liveview, however, the push_redirect and push_patch functions do not seem to be doing anything. I’m not sure where I’m going wrong but was wondering if someone could kindly point out where I’ve messed up or where my understanding is lacking on how this is meant to work, please.

When saving the item invoice in InvoiceFormComponent’s event handler, the expected behavior is that the socket is annotated to redirect (or even navigate away to another liveview using push_navigate) but that doesn’t appear to happen and the page simply reloads the same url.

I’ve tried to upgrade liveview from 0.20.12 to 0.20.14 (and phoenix from 1.7.11 to 1.7.14) although I saw no mention of a related bug in the changelog nor do I see other pointers to possible issues from there to 1.0.0-rc0, though 1.0.0-rc1 shows a bug related to Bandit that may be related?

and thanks in advance!

Router:

    live "/items/:id/stocks", ItemLive.Show, :stock
    live "/items/:id/add-stock", ItemLive.Show, :add_stock

Item show liveview actions:

  defp apply_action(socket, :stock, params) do
    socket
    |> assign_item_invoices()
  end

  defp apply_action(socket, :add_stock, params) do
    socket
    |> parse_params(params)
    |> assign(:invoice, %Invoice{status: :draft, invoice_type: :item_stock})
    |> assign(:item, Inventory.get_item!(params["id"]))
    |> assign(:vendors, VendorAccounts.list_vendors())
    |> assign(:warehouses, Warehousing.list_warehouses())
    |> assign(:page_title, page_title(socket.assigns.live_action))
  end

Item show html:

<%= if @live_action == :add_stock do %>
<.modal id="add-invoice-modal"
  on_cancel={JS.patch(~p"/#{current_locale()}/items/#{@item.id}/stocks")} >

  <.live_component id="invoice-for-item-stock"
                   module={MutakamelWeb.ItemLive.InvoiceFormComponent}
                   action={@live_action}
                   invoice={@invoice}
                   invoice_type={:item_stock}
                   item={@item}
                   vendors={@vendors}
                   warehouses={@warehouses}
                   return_to={~p"/#{current_locale()}/items/#{@item.id}/stocks"} />
</.modal>
<% end %>

InvoiceFormComponent:

  defp save_invoice(socket, :add_stock, invoice_params) do
    case Invoicing.create_invoice_for_item_stock(invoice_params) do
      {:ok, %{invoice: _invoice}} ->
        {:noreply,
         socket
         |> put_flash(:info, "Invoice created successfully")
         |> push_redirect(to: socket.assigns.return_to)} # <<< doesn't work!

      {:error, :invoice, %Ecto.Changeset{} = changeset, _} ->
        {:noreply, assign(socket, :form, to_form(changeset))}
    end
    {:noreply, socket}
  end

Sorry to be the bringer of bad news but you have an extra {:noreply, socket} at the end of your function overriding the return value :slight_smile:

Happens to the best of us!

2 Likes

:person_facepalming:t4: seriously, thank you … I spent much of my day thinking why this is not working!!

2 Likes