I'm just starting out with Alpine.js, I understand the basics but I'm having trouble applying them when moving functions outside of inline script tags.
For example, in index.html
:
<div x-data="{ loading: false }"/>
<button
onClick="post()"
:class="{ 'active': loading === true }"
>
Post Comment
</button>
</div>
if post()
was in main.ts
:
const postComment = () => {
this.loading = true;
};
window.postComment = postComment;
How do I make it so that this
isn't undefined?
I've found plenty of examples where functions are kept within index.html
, but none where they're in a separate file.
I'm just starting out with Alpine.js, I understand the basics but I'm having trouble applying them when moving functions outside of inline script tags.
For example, in index.html
:
<div x-data="{ loading: false }"/>
<button
onClick="post()"
:class="{ 'active': loading === true }"
>
Post Comment
</button>
</div>
if post()
was in main.ts
:
const postComment = () => {
this.loading = true;
};
window.postComment = postComment;
How do I make it so that this
isn't undefined?
I've found plenty of examples where functions are kept within index.html
, but none where they're in a separate file.
1 Answer
Reset to default 11You'll need to add the method to the AlpineJs instance to access the same scope. But you can do this with some object destructuring using the spread ...
operator:
In the page:
<div x-data="{
isLoading: false,
...utils
}">
// Your content
</div>
Then in your external script file:
const utils = {
post(){
this.isLoading = true
}
}
window.utils = utils
The nice thing about this is you could put everything you need for a loading indicator in this external object to use as a mixin wherever you need it.
Here's a working example: https://codepen.io/stephenoldham/pen/BapvyYr
Update for AlpineJs v3:
If you're trying to achieve the same goal in the latest version of AlpineJs you'll need to use the Data Directive:
In the page:
<div x-data="utils">
// Your content
</div>
Then in your external script file:
document.addEventListener('alpine:init', () => {
Alpine.data('utils', () => ({
isLoading: false,
post(){
this.isLoading = true
setTimeout(() => {
this.isLoading = false
}, 3000)
}
}))
})
Here's a working example: https://codepen.io/stephenoldham-the-vuer/pen/dyJEjRx?editors=1100
Further reading in the docs covers how to set initial values and more: https://alpinejs.dev/globals/alpine-data