phoenix_live_view icon indicating copy to clipboard operation
phoenix_live_view copied to clipboard

stale window location object in javascript after live_redirect

Open ringofhealth opened this issue 2 years ago • 5 comments

Environment

  • Elixir version (elixir -v): Elixir 1.13.4 (compiled with Erlang/OTP 24)
  • Phoenix version (mix deps): phoenix 1.6.11
  • Phoenix LiveView version (mix deps): phoenix_live_view 0.17.11
  • Operating system: macOs 12.2.1
  • Browsers you attempted to reproduce this bug on (the more the merrier): Chrome 104.0.5112.101
  • Does the problem persist after removing "assets/node_modules" and trying again? Yes/no: Yes

Actual behavior

windows.location.path when phx-hook during mount method remains the previous link value. when using live_redirect This is only reproduced on 0.17.11.

repro steps:

  1. have 2 links both with live_redirectand attach phx-hook on the parent container
  2. console.log(window.location.path) in the mount method of the hook
  3. click on the second link, with live_redirect. Observe the url bar change to the new link path, but the console log will have the prev path. when click on the same link again, the console log will have the new value updated.

Expected behavior

test on 0.17.10 - 0.17.5 whenever live_redirect link is clicked. the path logged on the mount method matches those on the location bar

ringofhealth avatar Sep 01 '22 04:09 ringofhealth

Is this happening specifically from live.html.heex by any chance? I have seen a similar issue when using live_patch but it seems to only be occurring when called from live.html.heex. Inside another liveview it appears to be working correctly.

bratsche avatar Sep 06 '22 17:09 bratsche

We need more information on what is going on here. Where is the hook element located? Can you share your hook code, etc? Thanks!

chrismccord avatar Sep 06 '22 18:09 chrismccord

I'm not able to reproduce the live_redirect issue, so what I'm seeing may be different. But I am able to reproduce my similar issue with live_patch in a minimal example, which I've posted on GitHub. The thing that has me a little confused is that it's not how I described above (re: live.html.heex). In this repo I'm just doing a live_patch from inside a normal live view and it's not updating the URL.

https://github.com/bratsche/nav_test

I've added a description in the README.md. Also note that you can change the phoenix_live_view version down to 0.7.10 and the issue I'm describing does not happen.

bratsche avatar Sep 07 '22 13:09 bratsche

I'm seeing the a similar thing in 0.17.11, as mentioned by the earlier poster, it doesn't happen in 0.17.10.

I'll share as much detail as I can.

What I'm seeing is this: when using live_patch I have to click the link twice for the URL to correctly reflect what's on the page. A single click happily renders the correct content, but the URL isn't correctly updated.

Here's a screen recording of the behaviour

https://user-images.githubusercontent.com/1583673/189511901-d7af76be-f4ae-4344-9209-72c7034f436a.mp4

The collection of links shown in the video are function components

  def nav_link(assigns) do
    assigns =
      assigns
      |> assign_new(:icon, fn -> false end)

    ~H"""
    <%= live_patch(to: @to, class: "flex items-center pl-3 my-0.5 transition-all duration-200 ease-in hover:bg-slate-200 dark:hover:bg-slate-800")  do %>
      <%= if @icon do %>
        <span class="material-icons material-symbols-outlined text-4xl mr-2">
          <%= @icon %>
        </span>
      <% end %>
      <span>
        <%= render_slot(@inner_block) %>
      </span>
    <% end %>
    """
  end

And they are called like this

        <.nav_link to={Routes.user_index_path(@socket, :index)} icon="manage_accounts">
          List all
        </.nav_link>

I've looked at a diff of the tags on GitHub, and can't see anything obvious to explain this issue https://github.com/phoenixframework/phoenix_live_view/compare/v0.17.10...v0.17.11

I've stepped through the JS debugger and noticed something strange.

The historyPatch function https://github.com/phoenixframework/phoenix_live_view/blob/e7cf73f759972d0166337fc1529ba2e522648d92/assets/js/phoenix_live_view/live_socket.js#L718-L723 get's called with a strange value at times in 0.17.11

In 0.17.10 the linkRef is always an incrementing integer, but in 0.17.11 it's sometimes a float (in this instance it was 13952.235).

Screen Shot 2022-09-11 at 11 43 17 am

I haven't been able to figure out why, but hopefully it helps folks familiar with the codebase. Apologies if this is a red herring!

mfeckie avatar Sep 11 '22 04:09 mfeckie

@chrismccord here is the code I have that is causing this issue

basically all this does is

  1. look at the child el of of the hook and look through each of the href
  2. look at current href
  3. mark element with is-active class if 1 and 2 is the same
Hooks.linkState = {
    mounted() {
        // there exist this bug where the path does not update. in liveview 0.17.11
        let _currentPath = window.location.pathname;
        if ($(this.el).attr('id') == 'side-bar-menu') {
            $(this.el)
                .find('a')
                .each((i, el) => {
                    if (_currentPath == $(el).attr('href')) {
                        $(el).parent('li').addClass('is-active');
                    }
                });
        } else {
            $(this.el)
                .find('a')
                .each((i, el) => {
                    if (_currentPath == '/' && $(el).attr('href') == '/') {
                        $(el).addClass('is-active');
                    } else if (
                        _currentPath.includes($(el).attr('href')) &&
                        $(el).attr('href') != '/'
                    ) {
                        $(el).addClass('is-active');
                    }
                });
        }
    },
};

The actual attachement happens in liveview components like so

 <ul class="main-menu" phx-hook="linkState" id="side-bar-menu">
          <li>
            <%= live_redirect to: Routes.collection_index_path(@socket,:index), class: "" do %>      
              <span class="gttext"><%= gettext("view all") %></span>
            <% end %>
          </li>
          <%= for %{name: name, id: id} <- @collections do %>
            <li>
              <%= live_redirect to: Routes.collection_show_path(@socket,:show, id), class: "" do %>    
                <span class="gttext"><%= name %></span>   
              <% end %>
            </li>
          <% end %>
</ul>

@bratsche I am seeing this both on live_redirect and live_patch

if you notice in @mfeckie's recording. When the click goes to the links for the first time. The url in the windows address actually does not change. When the same link is click again, then the location changes. This is my exact bug

ringofhealth avatar Sep 13 '22 04:09 ringofhealth

Hi all,

I also ran into this issue when upgrading live_view from 0.17.10 to 0.18.2.

As it seems the URL in the browser window is updating correctly. However, the window.location.href stays the same until the link is clicked twice in a row.

I'm using the new <.link> within the live.html.heex file

Any updates on this problem or did anybody manage to solve it?

Really appreciate the help!

alexanderbaetz avatar Oct 18 '22 09:10 alexanderbaetz

could this have been the culprit for this issue?

https://github.com/phoenixframework/phoenix_live_view/commit/e7cf73f759972d0166337fc1529ba2e522648d92#r89315641

ringofhealth avatar Nov 09 '22 02:11 ringofhealth

I found it only happens with live_patch and suspect I may have been using the 'wrong' thing.

I've switched to live_redirect or <.link nagivate={my_url}> and it seems to be fine after that

mfeckie avatar Nov 09 '22 03:11 mfeckie

Yes, in my case I was using it wrong. I was just patching my way everywhere, but really you only want to use live_patch (or <.link patch={...}> within the same LiveView, and otherwise use <.link navigate={...}> or whatever.

bratsche avatar Nov 09 '22 04:11 bratsche

We should still fallback to navigate without errors, but good to know it can be address within the app.

josevalim avatar Nov 09 '22 07:11 josevalim

We now fallback without errors. Thanks!

chrismccord avatar Jan 19 '24 21:01 chrismccord