Sanjibukai

Sanjibukai

Hello,

It seems that any LiveView sigil is expected to have in its scope an assigns map.
So not a keyword list or anything else, but a map.

But often I end up with a Dialyzer error (or warning) that The pattern can never match the type

Consider the following simple example for a helper:

defp product_link(product) do
  assigns = %{name: product.name, url: product.url}

  ~L"""
  <a href="<%= @url %>">
    <%= @name %>
  </a>
  """
end

And calling simply like that:

<%= product_link(product) %>

With ElixirLS Dialyzer, I got the following warning/error:

The pattern can never match the type.

Pattern:
%{:__changed__ => _}

Type:
%{:name => _, :url => _}

Now if instead I do the following, I don’t get the error but it’s more verbose on the calling side (particularly bothering when I have a list with more than two keywords pair).

defp product_link(assigns) do
  assigns = Enum.into(assigns, %{})

  ~L"""
  <a href="<%= @url %>">
    <%= @name %>
  </a>
  """
end

And calling like that:

<%= product_link(name: product.name, url: product.url) %>

But in this case I don’t get any warning/error.

So I wanted to know first, what exactly is the meaning of that warning?
Where does it come from?

Is it possible to fix it?
I’m not using any spec, but does defining some specs could prevent this error? (Though, it’s a private function so I’m not sure for that).

If not, how to disable only that warning/error here?

I didn’t defined anything particular to use Dialyzer, but it came for free with ElixrLS in VSCode. So in the meantime to learn more about specs, I rather want to stick with this default usage and try to get no warnings/errors.

And lastly, besides the Dialyzer warning, what is the best way to handle the assigns in LiveView sigils?

Thank you very much folks!

Showing Posts 1 to 9

Sanjibukai

Sanjibukai OP

Well I found a way to mix both versions, ie. having a simpler call while not having any error.
Simply build the keyword list in the function like so:

defp product_link(product) do
  assigns =
    [name: product.name, url: product.url] 
    |> Enum.into(%{})

  ~L"""
  <a href="<%= @url %>">
    <%= @name %>
  </a>
  """
end

But I don’t know if it’s a valid workaround and if it’s correct idiomatic Elixir.
Also, while doing this I don’t know at all why this is needed..

Any thought are welcome..

Sanjibukai

Sanjibukai OP

Hello everybody…
I’m coming back to this topic…
The following is obviously correct and match to:

%{name: "my product"} = [name: "my product"] |> Enum.into(%{})

But why using the left hand side in a liveview template brings the mentioned error while using the right hand side doesn’t bring any error?

I hope I’ll receive some answer this time :wink:

kokolegorille

kokolegorille

You can remove the warning by using…

assigns = %{__changed__: nil, name: product.name, url: product.url}

I guess it needs this key.

Sanjibukai

Sanjibukai OP

Indeed, this way the warning disappears.
But it seems weird to add that key out of context..

But for a better understanding..
How people are managing this case?
But maybe it is not a commonly used pattern (though it seems common enough to me) particularly when trying to “componentize” UI parts…

Is it possible to rather disable that very warning?
If so, could that cause some side effect else where?

Thank you very much BTW..

florish

florish

Hi, bumping this topic a bit, as I’m running into the same issue after following the suggestion made here in the LiveView docs:

Specifically this code example:

def my_button(text, click) do
  assigns = %{text: text, click: click}

  ~L"""
  <button class="css-framework-class" phx-click="<%= @click %>">
      <%= @text %>
  </button>
  """
end

I read this as a best practice, and ran into the dialyzer error as described by the topic starter:

The pattern can never match the type.

Pattern:
%{:__changed__ => _}

Type:
%{:foo => [any()]}

I’d love to hear from others how they worked around this other that adding a (functionally speaking unneeded) :__changed__ key to the assigns variable inside the function outputting a ~L.

trisolaran

trisolaran

Hello! I’m glad I found this thread cause I just bumped into the very same problem. Thanks for the suggested workarounds. Still, it would be nice to understand where the errors is coming from. Maybe somebody has found some valuable insights in the meantime.

michallepicki

michallepicki

This may be hard to debug because of macros generate code with generated: true to supress Dialyzer warnings for all the dead code they generate, and in this case probably the root cause is invalid / slightly incompatible spec for one of the functions called from generated code, but the warning pointing to that place is also supressed.

josevalim

josevalim

Creator of Elixir

The issue in this case is exactly that we were not marking it as generated. I will have fixed it on LiveVIew master.

michallepicki

michallepicki

Just found it myself as well, by commenting out all pattern matches on a map with :__changed__ field in live view code one by one, it was the one in Phoenix.LiveView.Engine.

So in this case this is one of those only-slightly annoying dialyzer warnings about dead code being detected. These don’t propagate so it’s good enough to mark as generated

— All posts loaded —

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
FlyingNoodle
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
webofbits
Aludel - LLM Evaluation Workbench Aludel is an embeddable Phoenix LiveView dashboard for evaluating and comparing LLM prompts across mult...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews