lpetrucci
lpetrucci

Reputation: 1677

Alpine.js: How do I access x-data from a function in an external 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.

Upvotes: 3

Views: 27143

Answers (1)

Steve O
Steve O

Reputation: 5774

You'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

Upvotes: 11

Related Questions