Upgraded to 1.7 live view 0.18, I’m getting odd behavior with put_flash

Hi there:

I have upgraded to 1.7 live view 0.18, I’m getting this odd behavior with put_flash, and suddenly this:

{:noreply,
         socket
         |> put_flash(:info, "Event created successfully")
         |> push_redirect(to: "/events/#{event.slug}/edit")}

Does not put any flash, by the other hand if I don’t do the redirect, it works.

Also in some Live Components, I have changed the push_redirect to push_navigate, in some cases works, in others don’t. I have realized this because I have some integration tests that failed, but I have not 100% coverage and I assume that my app now is completely broken by this API change :frowning:

2 Likes

The put_flash/3 docs include the following notes that seem relevant:

Note: While you can use put_flash/3 inside a Phoenix.LiveComponent, components have their own @flash assigns. The @flash assign in a component is only copied to its parent LiveView if the component calls push_navigate/2 or push_patch/2.

Note: You must also place the Phoenix.LiveView.Router.fetch_live_flash/2 plug in your browser’s pipeline in place of fetch_flash for LiveView flash messages be supported, for example:

import Phoenix.LiveView.Router

pipeline :browser do
  ...
  plug :fetch_live_flash
end
3 Likes

Hi, thanks for your reply, yes, I have the fetch_live_flash on my pipeline.

To persist the flash message across redirects in LiveView 0.18, you can use the put_session function instead of put_flash .

|> put_session(:flash, %{info: “Event created successfully”})
|> push_redirect(to: “/events/#{event.slug}/edit”)}

You can pull that info out of session when you need it using fetch_session.

Hi @BradS2S it seems that put_session is not available for live view socket conn.

It’s in Plug.Conn

It’s just abstracting the use of ETS so it might be more straightforward to use that directly.

note sure about this, in the live view we have access to socket not plug conn, maybe that’s the issue? put_session is not available on live components

Blind shot here but looks like your redirect path is missing the ~p. What if you change it to ~p"/events/#{event.slug}/edit"?

redirects are ok, and no errors on the console. it just does not render the flash messages. I’m doing this inside live_component

Oh I missed it it’s push_navigate Phoenix.LiveView — Phoenix LiveView v0.18.16

But it should work. I’ll test in the morning if you’re still having issues by then.

yeah I’ve tried push_navigate and push_patch and nothing … :frowning:

oh, I think you were right! there was an error and I didn’t see it. I will be do some tests tomorrow but I think the mistery is solved

1 Like

Any updates on this?

it works on some components but no it all of them… not sure what could be the problem.

this is a video that explains the error and shows that it is working on one live component but not in the other

seems that the issue here is that I using assign, which is really weird, so this works:

    {
      :noreply,
      socket
      |> put_flash(:info, "Event updated successfully")
      |> push_patch(to: "/events/#{socket.assigns.event.slug}/edit/attendees?tot=1")
    }

but this doesn’t

    {
      :noreply,
      socket
      |> assign(:open_modal, false)
      |> assign(:status, :success)
      |> put_flash(:info, "Event updated successfully")
      |> push_patch(to: "/events/#{socket.assigns.event.slug}/edit/attendees?tot=1")
    }

also in that context, a push_navigate doesn’t work either, I mean, it redirects but does not set the flash.

Can you provide a minimal app that reproduces the issue and do a bug report? For example, does it happen if you build a new Phoenix app and run mix phx.gen.live?

FWIW, I did give it a try in a new Phoenix app and I could not reproduce it but it did give me an idea about what could be wrong. When you submit your modal, are you by any chance navigating twice? Check your logs, see HANDLE PARAMS appears twice.

Like regular flash, LiveView flash clears out on page navigation. So if you are doing a double navigation, it will disappear. Feel free to share the code to your modal too!

My modal that includes a <.live_component> doesn’t show any flash either when issued from within its live_view.

{:error, reason} ->
   {:noreply,
     socket
     |> assign(:upload_progress, 0)
     |> put_flash(:error, "Error uploading #{finished_entry.client_name}: #{reason}")}

upload_progress that affects a progress bar correctly updates at the same time. At that moment - actually before the assign happens, the logger reports

iex> [info] JOINED lvu:1 in 1ms
  Parameters: %{"token" => "SFMyNTY.g2gDaAJhBXQAAAADZAADY2lkYQFkAANwaWRYZAAUdGVzdEBERVNLVE9QLUNVTDBEMzUAAAOLAAAAAGQLVkhkAANyZWZoAm0AAAAUcGh4LUYwdXZXLVJnWUp6XzlBa0NtAAAAATFuBgAoSwjWhgFiAAFRgA.RhZfTCO-aK-d_eKoSgMyPbIlzkG6PMWHt-8T1zdMRYQ"}

(I’m guessing, it comes from a <.live_file_input)

A side note, could be distantly related, for some reason I have to do send_update when I need to update uploaded_files to []). A regular assign(socket, uploaded_files: []) does not update the child modal that contains a live component. It surely is passed down to the live component as a property upload_progress={@upload_progress} and it surely differs from a list containing at least one item.