CherryPoppins
I’m having an issue with alpinejs where I am seemingly loosing alpine after performing a task where liveview basically validates a changeset and reassigns/updates @changeset, I don’t think this part is important to the issue. While this changeset is getting validated I have a loader that uses x-show to show it or hide it based on a bool value from an Alpine.store. The loader is turn on with an @click and turned off by the liveview sending a message to a hook that changes the bool in Alpine.store. The loader is getting stuck to on/show (or its natural state of display: block) because I am loosing that x-show. Typing Alpine.start() into the console fixes the issue so I know it is alpine getting uninitialized or not loading back up or something. Anyone else having this issue with liveview and alpine?
Alpine setup:
import Alpine from 'alpinejs'
window.Alpine = Alpine
Alpine.start()
...
const liveSocket = new LiveSocket('/live', Socket, {
params: {_csrf_token: csrfToken},
dom: {
onBeforeElUpdated(from, to) {
if (from._x_dataStack) {
window.Alpine.clone(from, to)
window.Alpine.initTree(to)
}
},
},
hooks: Hooks,
})
May or may not be relevant to this issue but I am also getting this error sometimes in the console on this liveview:
module.esm.js:2288 Uncaught (in promise) TypeError: i is not a function at module.esm.js:2288
the function, which seems to be coming from alpine, the error is referring to with the call to i() (23 lines down)
window.Element.prototype._x_toggleAndCascadeWithTransitions = function(el, value, show, hide) {
let clickAwayCompatibleShow = () => requestAnimationFrame(show);
if (value) {
el._x_transition ? el._x_transition.in(show) : clickAwayCompatibleShow();
return;
}
el._x_hidePromise = el._x_transition ? new Promise((resolve, reject) => {
el._x_transition.out(() => {
}, () => resolve(hide));
el._x_transitioning.beforeCancel(() => reject({isFromCancelledTransition: true}));
}) : Promise.resolve(hide);
queueMicrotask(() => {
let closest = closestHide(el);
if (closest) {
if (!closest._x_hideChildren)
closest._x_hideChildren = [];
closest._x_hideChildren.push(el);
} else {
queueMicrotask(() => {
let hideAfterChildren = (el2) => {
let carry = Promise.all([
el2._x_hidePromise,
...(el2._x_hideChildren || []).map(hideAfterChildren)
]).then(([i]) => i());
delete el2._x_hidePromise;
delete el2._x_hideChildren;
return carry;
};
hideAfterChildren(el).catch((e) => {
if (!e.isFromCancelledTransition)
throw e;
});
});
}
});
};
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #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
- #ecto-query
- #blog-post
- #elixirconf-us
- #elixir-ls
- #ai
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming











Showing Posts 1 to 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
ruslandoga
Try removing
Alpine.initTree(to)fromonBeforeElUpdated. I had similar problems with it. The errors you are seeing might be easier to debug if you enable source maps.akoutmos
I am guessing that since you are using a changeset, that the DOM element that you are interacting with is a form. In the past, I have had issues with Alpine state stored on the form tags (iirc Morphdom deals with patching forms differently that it does patching other HTML tags).
To circumvent the Morphdom form issues, I leveraged Spruce to store the Alphine state outside of the form tag GitHub - ryangjchandler/spruce: A lightweight state management layer for Alpine.js. 🌲 · GitHub. With the release of Alpine 3.x though, what functionality Spruce offered is now supported directly in AlpineJS.
CherryPoppins
So I am actually using
Alpine.state('loader', false)to manage state here, initialized in a hook. My loader is inside of aformthough so this could be the issue. I’ll have to do a bit of refactoring to test it out, but thanks for the lead!msimonborg
Have you tried adding
phx-update=“ignore”to the loader element tag? I’m Not actually sure if this would work on an element inside the form component, but might be worth tryingCherryPoppins
Yes, I tried pretty much everything back then. We ended up abandoning Apline because of too many issues at the time. It may be more stable now, this was quite a while ago and they seemed to be constantly evolving.
msimonborg
Sorry, I just realized how old this was! It showed up on my suggested feed and didn’t realize the date : ) I hope you found something that works for you. Alpine is working well for me today but honestly I just started with it.
chocolatedonut
This is vaguely similar to what I’m experiencing. Here’s a minimal project that reproduces the issue. I’d be grateful if anyone can take a look.
The issue is that when
A) rendering directly from a LiveView, everything works. But when
B) the rendering is moved to a LiveComponent, Alpine’s
x-show(or something else) “breaks”: the search results still show, but not immediately on typing (only after users also presses the Enter key).In other words, moving the
render/1shown below (as well as some fewhandle_event/3) from:live_viewto:live_componentsomehow breaks and Alpine’s
x-showdoesn’t show the<ul>immediately. It does show up but only if one also then presses say the Enter key, or defocuses-and-refocuses the search<input>with a mouse, etc.And the relevant lines from
app.js:Visually, I only see the following differences in the relevant HTML between the
:live_view(left) and the:live_component(right):Other somewhat related threads:
chocolatedonut
I’ve fixed the error reported in my message above by merely adding an
idattribute on the element that also has Alpine’sx-dataattribute. Why was/is the missingidattribute an issue for Alpine? (It seems like anyidattribute will do.)It’s unclear why is it problematic if an
idattribute isn’t explicitly provided. In other words, how come theLiveComponent-generated “id” doesn’t suffice? This is seen in my previous message above, on the image diff of two HTMLs; specifically, the auto-generatedidis in the top red rectangle.Investigating the LiveSocket’s
domobject, specifically theonBeforeElUpdated(from, to)callback (as seen inapp.jsabove) does suggest there’s some difference already on the initial load, before any user interaction: on load, thefromandtoelements only get printed in the console when the mentionedidis given (otherwise not).Seems like I should first figure out why
onBeforeElUpdateddoes (not) get called whenidis (not) provided. Please let me know if you see where I’m misusing Alpine and/or LV; I’ll admit already that having both LV’s:if=and Alpine’sx-showon the same element seems superfluous and asking for trouble.PS. For Alpine, I’ve looked into docs at 1) the “Essentials” section, 2) on $id, 3) on
x-iddirective, and 4) on Alpine.data (and glanced at other sections as well) and couldn’t find any mention of a requiredidattribute, or anything that would explain this behaviour.cmo
Or put an
idon all alpine scopes.And yes, you’re asking for (and getting) trouble. Personally, I ripped alpine out first chance I got. There is a certain elegance to alpine but it’s not worth the headache for me.
chocolatedonut
Thanks for the reply! Indeed, I’m already eyeing if/how JS Commands & Hooks might be able to replace Alpine.
Still, I’d be curious to read from you or anyone that knows why exactly is the above behaviour different between
A) a LiveComponent-provided
idattribute (seen on the image above, in the top red rectangle), vs.B) my own, explicitly set
idattribute (on the same HTML element, the top-level<div>)