Access Alpine.js 3 component data/state from outside its scope

Alpine JS is great, but it can get a bit tricky trying to manage multiple components in different places on your website. Sometimes you want to trigger a components method on the fly from somewhere unrelated without having to wrap the trigger component into scope and restructuring the whole app.

Alpine 2

In Alpine 2 there was the ability to access a component’s state using the following.

const component = document.querySelector('.myComponent');

// alpine object
const alpineObject = component.__x;

// alpine data
const alpineData = component.__x.$data;

Alpine 3

In alpine 3 this is not available and there is no documentation to do so.

There is a way, however. This is not recommended, official or documented as far as I can tell, but I found the following.

const component = document.querySelector('.myComponent');

// Component functions
const componentFunctions = component._x_dataStack[0];

// inherited functions
const inheritedFunctions = component._x_dataStack[1];

// run a method of the component
componentFunctions.functionName()

As you can see, Alpine 3 allows for nested x-data components, and provides scoped methods and properties through the _x_dataStack array, with index 0 being it’s own properties and index 1 being inherited.

I haven’t tested, but for multiple nested components with x-data I imagine this array will increase the deeper the nest goes.

How did I discover this?

For one, it’s Javascript. There’s no private methods and everything is there if you delve deep enough.

I was trying to run a method on a slideshow component, without having to restructure my application.

In the below example you can also see that if you know the name of the store, you can use document.querySelector to get access to any store on the page.

If I console.log the slideshow constant, I will get the following, which is a bit rubbish as I want to see what methods and properties are attached.

If I console.log Object.keys around this however….

And there you go. I’m not sure what the other keys give access to, but if something looks familiar then the obvious solution is to have a poke about. From testing, I believe _x_refs are your $refs for that scope.