I'm using alpine.js v3 with some modules for the data
import Foo from './foo';
import Bar from './bar';
window.Alpine = Alpine;
window.Alpine.data('data', () => ({
foo: Foo(),
bar: Bar(),
}));
window.Alpine.start();
<body x-data="data">
Whenever I try to access the data
<button @click="data.foo.doSomething()">
I get the error
Alpine Expression Error: data is not defined
Do I have to add it with the x-data directive anyways?
(update)
And how can I access this data from another component, e.g.
Get status of the Foo component and call a method of Bar:
window.Alpine.bind('SomeButton', (name) => ({
'x-init'(){
const data = window.Alpine.$data;
if(data.foo.status === 'open'){
data.bar.doSomething();
}
}
});
With Alpine.data() you define a component. After that you can access directly all of the properties of the component inside the element where you applied it via x-data. Here data is the component, so you don't have to prefix its properties with data.:
<div x-data="data">
<button @click="foo.doSomething()">Call doSomething()</button>
</div>
Answering your second question: since you have one "global" component that you applied to the topmost element (body), each child component can access the properties of this parent component. So inside SomeButton "bind-object"-type component, we can access them in the component's definition using the this. prefix.
window.Alpine.bind('SomeButton', () => ({
'@click'() {
if (this.foo.status === 'open') {
this.bar.doSomething()
}
}
})
Here we attached our logic to the click-event: we call bar.doSomething() if the status is 'open'.
<div x-data="data">
<button x-bind="SomeButton">Call bar.doSomething() if status is 'open'</button>
</div>