B45i
B45i

Reputation: 2602

Alpine.js Cant bind x-data to functin in external js file

I'm creating an app with alpine.js

this is the context of my index.html file

<!DOCTYPE html>
<html>
  <head>
    <title>Hello Alpine</title>
    <meta charset="UTF-8" />
  </head>

  <body>
    <div id="app" x-data="app()">
      <div>
        <button x-on:click="open">Open</button>

        <div x-show="isOpen()" x-on:click.away="close">
          // Dropdown
        </div>
      </div>
    </div>

    <script src="src/index.js"></script>
    <script>
      function app() {
        return {
          show: false,
          open() {
            this.show = true;
          },
          close() {
            this.show = false;
          },
          isOpen() {
            return this.show === true;
          }
        };
      }
    </script>
  </body>
</html>

This code is working fine, but however, if I move the app function to index.js I'm getting an error in the console.

index.html:

<!DOCTYPE html>
<html>
  <head>
    <title>Hello Alpine</title>
    <meta charset="UTF-8" />
  </head>

  <body>
    <div id="app" x-data="app()">
      <div>
        <button x-on:click="open">Open</button>

        <div x-show="isOpen()" x-on:click.away="close">
          // Dropdown
        </div>
      </div>
    </div>
    <script src="src/index.js"></script>
  </body>
</html>

and index.js

import "./styles.css";
import "alpinejs";

function app() {
  return {
    show: false,
    open() {
      this.show = true;
    },
    close() {
      this.show = false;
    },
    isOpen() {
      return this.show === true;
    }
  };
}

When I run this code, I get the following error:

alpine.js:1907 Uncaught TypeError: app is not a function at eval (eval at tryCatch.el.el (alpine.js:NaN), :3:54)

CodeSandbox Link is here

Upvotes: 3

Views: 8980

Answers (1)

Irfan
Irfan

Reputation: 1030

By default, alpine is going to look for the component in the window level. So the issue can be solved by making an app variable in the window which is your exact same function.

import "./styles.css";
import "alpinejs";

window.app = function () {
  return {
    show: false,
    open() {
      this.show = true;
    },
    close() {
      this.show = false;
    },
    isOpen() {
      return this.show === true;
    }
  };
};

There's a free video tutorial about extracting alpine js components in Laracasts, you can view it here.

Upvotes: 11

Related Questions