simoncocking
We’re running into an odd problem with AlpineJS and Phoenix LiveView, whereby Alpine reacts to the previous value of an assign when it changes. For example, with the following LEEx (lifted verbatim from Patrick Thompson’s excellent blog post:
<div id="counter" x-data="{count: <%= count %>}">
<h1>The assigns count is: <span><%= @count %></span></h1>
<h1>The alpine count is: <span x-text="count"></span></h1>
</div>
With Alpine v2, both the assigns count and Alpine count are kept in sync whenever the assign is updated however with Alpine v3, the Alpine counter is always one update behind the assign.
I’ve illustrated the whole problem in this Loom video.
Has anyone else seen (or can reproduce) this issue? The full LiveView is as follows:
defmodule MyApp.AlpineLive do
use Phoenix.LiveView
@impl Phoenix.LiveView
def render(assigns) do
~L"""
<div id="counter" class="m-8" x-data="{count: <%= @count %>}">
<h1>The assigns count is: <span><%= @count %></span></h1>
<h1>The alpine count is: <span x-text="count"></span></h1>
<button class="button button-primary" phx-click="decrement"> Decrement </button>
<button class="button button-primary" phx-click="increment"> Increment </button>
</div>
"""
end
@impl Phoenix.LiveView
def mount(_, _, socket) do
count = if connected?(socket), do: 5, else: 0
{:ok, assign(socket, count: count)}
end
@impl Phoenix.LiveView
def handle_event("increment", _, socket) do
{:noreply, update(socket, :count, &(&1 + 1))}
end
def handle_event("decrement", _, socket) do
{:noreply, update(socket, :count, &(&1 - 1))}
end
end
FWIW our app.js integrates AlpineJS with the following option on the LiveSocket (which supports both Alpine v2 and v3):
dom: {
onBeforeElUpdated(from, to) {
if (!window.Alpine) return;
if (from.nodeType !== 1) return;
// AlpineJS v2
if (from.__x) window.Alpine.clone(from.__x, to);
// AlpineJS v3
if (from._x_dataStack) window.Alpine.clone(from, to);
},
},
Trending in Questions
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
Documentation
While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
Hello,
I’m trying to build a basic Phoenix web-app, and I’d like to use Tailwind.
However, when I launch mix phx.server, I get an error...
New
Hi everyone,
I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding.
I sta...
New
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New
I’m working on a small exercise involving update_in/3, and I came up with this solution:
data = %{
name: "Periodic Table",
category:...
New
I’ve got trouble wrapping my head around the order in which functions are called in this snippet (from Phoenix’s authentication):
toke...
New
Other Trending Topics
Edit: 2026 May 15 - This post is archived.
Mob is alive!!
Main docs: mob v0.7.11 — Documentation
A bit of explanation for the slightly c...
New
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
I am happy to introduce the very α version of the new programming language compiled to BEAM.
Welcome Cure.
It has literally three kille...
New
Hobbes is a low-level distributed database for the Elixir programming language.
Hobbes provides a simple, safe, and scalable storage lay...
New
Hi everyone!
The first release candidate for the Expert language server project is now available!
We’ve published a press release detai...
New
A little off-topic, but I feel like people here have a good head on their shoulders.
I used to be quite good at making software. Was luc...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ai
- #ecto-query
- #elixirconf-us
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #elixirconf-eu
- #api
- #forms
- #metaprogramming
- #hex











Showing Posts 6 to 1- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
mchlsync
I got this error if I use
<%= @count %>. I triedx-data={"{ count: #{@count} }"too but it doesn’t show the actual value in Chrome dev tool. it is not working as well.c4710n
This workaround would be fine if the Alpine component only contains shadowed assigns of LiveView.
But, if the Alpine component is maintaining its own states besides of the shadowed assigns of LiveView. Every time the shadowed assigns of LiveView updates, the Alpine component’s own states will be reset by
window.Alpine.initTree(to).That’s not expected.
For example:
So, I prefer the workaround provided by simoncocking.
larryweya
I struggled for a sometime with this issue, including using x-init to set the value without success, the only thing that has worked is the addition of
window.Alpine.initTree(to)after thewindow.Alpine.clone(from, to)call.polypush135
I’ve tried this but with no luck
I have seen that if you call Alpine start again it re initializes and shows the correct data. My thought here is this is due to the way we are calling clone or what needs to happen to correctly re initialize
Any how heres my reproducible code.
https://github.com/MorphicPro/morphic_pro
Edit: so this looks like a possible solution
Alpine.initTree()Edit Edit:
Ok so I found it
and you don’t need to use x-init, Also heres something odd., look at what happens if you only use
window.Alpine.initTree(to)But after inspecting the_x_dataStackarray I’m not sure if that’s the correct way to do this.Also this Expose the initTree method by KevinBatdorf · Pull Request #1648 · alpinejs/alpine · GitHub
polypush135
Thanks for showing this new dom watcher. I was not seeing any console logs so I assumed it had not changed, but infact it was this that was the source of my issues.
simoncocking
So we’ve identified a workaround; the
x-databehaviour in Alpine v3 appears to have changed, but it can be achieved as follows: