Alpine.js Playground
Examples Newsletter

Magic Properties on `this`

tl;dr of the table (as of Alpine.js v2.3.x): $el, $refs, $nextTick and $watch are accessible from handlers for every directive (except x-data).

See the full post on How to Access Alpine.js Magic Properties from inline handlers and function/component methods

Get access to more Alpine.js content by purchasing Alpine.js Knowledge Base Membership

Hook Magic property Presence
x-data $el false
x-data $refs false
x-data $event false
x-data $dispatch false
x-data $nextTick false
x-data $watch false
x-init $el true
x-init $refs true
x-init $event false
x-init $dispatch false
x-init $nextTick true
x-init $watch true
x-text handler $el true
x-text handler $refs true
x-text handler $event false
x-text handler $dispatch false
x-text handler $nextTick true
x-text handler $watch true
x-html handler $el true
x-html handler $refs true
x-html handler $event false
x-html handler $dispatch false
x-html handler $nextTick true
x-html handler $watch true
x-bind handler $el true
x-bind handler $refs true
x-bind handler $event false
x-bind handler $dispatch false
x-bind handler $nextTick true
x-bind handler $watch true
x-show handler $el true
x-show handler $refs true
x-show handler $event false
x-show handler $dispatch false
x-show handler $nextTick true
x-show handler $watch true
<div 
  x-data="{ state: 'Initialised' }" class="flex flex-col"
>
  <div 
    x-data="controller()" 
    x-init="init()"
  >
    <button class="flex bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded" 
      x-on:click="test()"
    >
      Test magic properties for 
        x-on
    </button>
    <span 
      x-text="text()"
    ></span>
    <span 
      x-html="html()"
    ></span>
    <span 
      x-bind:custom-attr="bind()" custom-attr=""
    ></span>
    <span 
      x-show="show()" style="display: none;"
    ></span>
    <p>
      <strong>tl;dr of the table (as of Alpine.js v2.3.
        x): </strong>
      <code
      >$el</code>, <code>$refs</code>, <code>$nextTick</code> and
      <code>$watch</code> are accessible from handlers for every directive
      (except <code>
        x-data</code>).
    </p>
    <p>
      See the full post on
      <a class="text-blue-500 hover:text-blue-800 hover:underline" href="https://codewithhugo.com/alpinejs-magic-property-access/"
      >How to Access Alpine.js Magic Properties from inline handlers and
        function/component methods</a>
    </p>
    <p
    >
      Get access to more Alpine.js content by purchasing
      <a class="text-blue-500 hover:text-blue-800 hover:underline" href="/handbook">Alpine.js Knowledge Base Membership</a>
    </p>

    <table>
      <thead>
        <tr>
          <td>Hook</td>
          <td>Magic property</td>
          <td>Presence</td>
        </tr>
      </thead>
      <tbody>
        <template 
          x-for="entry in table"
        >
          <tr>
            <td 
              x-text="entry[0]"
            ></td>
            <td 
              x-text="entry[1]"
            ></td>
            <td 
              x-text="entry[2]"
            ></td>
          </tr>
        </template>
      
          <tr>
            <td 
              x-text="entry[0]"
            >
              x-data</td>
            <td 
              x-text="entry[1]"
            >$el</td>
            <td 
              x-text="entry[2]"
            >false</td>
          </tr>
        
          <tr>
            <td 
              x-text="entry[0]"
            >
              x-data</td>
            <td 
              x-text="entry[1]"
            >$refs</td>
            <td 
              x-text="entry[2]"
            >false</td>
          </tr>
        
          <tr>
            <td 
              x-text="entry[0]"
            >
              x-data</td>
            <td 
              x-text="entry[1]"
            >$event</td>
            <td 
              x-text="entry[2]"
            >false</td>
          </tr>
        
          <tr>
            <td 
              x-text="entry[0]"
            >
              x-data</td>
            <td 
              x-text="entry[1]"
            >$dispatch</td>
            <td 
              x-text="entry[2]"
            >false</td>
          </tr>
        
          <tr>
            <td 
              x-text="entry[0]"
            >
              x-data</td>
            <td 
              x-text="entry[1]"
            >$nextTick</td>
            <td 
              x-text="entry[2]"
            >false</td>
          </tr>
        
          <tr>
            <td 
              x-text="entry[0]"
            >
              x-data</td>
            <td 
              x-text="entry[1]"
            >$watch</td>
            <td 
              x-text="entry[2]"
            >false</td>
          </tr>
        
          <tr>
            <td 
              x-text="entry[0]"
            >
              x-init</td>
            <td 
              x-text="entry[1]"
            >$el</td>
            <td 
              x-text="entry[2]"
            >true</td>
          </tr>
        
          <tr>
            <td 
              x-text="entry[0]"
            >
              x-init</td>
            <td 
              x-text="entry[1]"
            >$refs</td>
            <td 
              x-text="entry[2]"
            >true</td>
          </tr>
        
          <tr>
            <td 
              x-text="entry[0]"
            >
              x-init</td>
            <td 
              x-text="entry[1]"
            >$event</td>
            <td 
              x-text="entry[2]"
            >false</td>
          </tr>
        
          <tr>
            <td 
              x-text="entry[0]"
            >
              x-init</td>
            <td 
              x-text="entry[1]"
            >$dispatch</td>
            <td 
              x-text="entry[2]"
            >false</td>
          </tr>
        
          <tr>
            <td 
              x-text="entry[0]"
            >
              x-init</td>
            <td 
              x-text="entry[1]"
            >$nextTick</td>
            <td 
              x-text="entry[2]"
            >true</td>
          </tr>
        
          <tr>
            <td 
              x-text="entry[0]"
            >
              x-init</td>
            <td 
              x-text="entry[1]"
            >$watch</td>
            <td 
              x-text="entry[2]"
            >true</td>
          </tr>
        
          <tr>
            <td 
              x-text="entry[0]"
            >
              x-text handler</td>
            <td 
              x-text="entry[1]"
            >$el</td>
            <td 
              x-text="entry[2]"
            >true</td>
          </tr>
        
          <tr>
            <td 
              x-text="entry[0]"
            >
              x-text handler</td>
            <td 
              x-text="entry[1]"
            >$refs</td>
            <td 
              x-text="entry[2]"
            >true</td>
          </tr>
        
          <tr>
            <td 
              x-text="entry[0]"
            >
              x-text handler</td>
            <td 
              x-text="entry[1]"
            >$event</td>
            <td 
              x-text="entry[2]"
            >false</td>
          </tr>
        
          <tr>
            <td 
              x-text="entry[0]"
            >
              x-text handler</td>
            <td 
              x-text="entry[1]"
            >$dispatch</td>
            <td 
              x-text="entry[2]"
            >false</td>
          </tr>
        
          <tr>
            <td 
              x-text="entry[0]"
            >
              x-text handler</td>
            <td 
              x-text="entry[1]"
            >$nextTick</td>
            <td 
              x-text="entry[2]"
            >true</td>
          </tr>
        
          <tr>
            <td 
              x-text="entry[0]"
            >
              x-text handler</td>
            <td 
              x-text="entry[1]"
            >$watch</td>
            <td 
              x-text="entry[2]"
            >true</td>
          </tr>
        
          <tr>
            <td 
              x-text="entry[0]"
            >
              x-html handler</td>
            <td 
              x-text="entry[1]"
            >$el</td>
            <td 
              x-text="entry[2]"
            >true</td>
          </tr>
        
          <tr>
            <td 
              x-text="entry[0]"
            >
              x-html handler</td>
            <td 
              x-text="entry[1]"
            >$refs</td>
            <td 
              x-text="entry[2]"
            >true</td>
          </tr>
        
          <tr>
            <td 
              x-text="entry[0]"
            >
              x-html handler</td>
            <td 
              x-text="entry[1]"
            >$event</td>
            <td 
              x-text="entry[2]"
            >false</td>
          </tr>
        
          <tr>
            <td 
              x-text="entry[0]"
            >
              x-html handler</td>
            <td 
              x-text="entry[1]"
            >$dispatch</td>
            <td 
              x-text="entry[2]"
            >false</td>
          </tr>
        
          <tr>
            <td 
              x-text="entry[0]"
            >
              x-html handler</td>
            <td 
              x-text="entry[1]"
            >$nextTick</td>
            <td 
              x-text="entry[2]"
            >true</td>
          </tr>
        
          <tr>
            <td 
              x-text="entry[0]"
            >
              x-html handler</td>
            <td 
              x-text="entry[1]"
            >$watch</td>
            <td 
              x-text="entry[2]"
            >true</td>
          </tr>
        
          <tr>
            <td 
              x-text="entry[0]"
            >
              x-bind handler</td>
            <td 
              x-text="entry[1]"
            >$el</td>
            <td 
              x-text="entry[2]"
            >true</td>
          </tr>
        
          <tr>
            <td 
              x-text="entry[0]"
            >
              x-bind handler</td>
            <td 
              x-text="entry[1]"
            >$refs</td>
            <td 
              x-text="entry[2]"
            >true</td>
          </tr>
        
          <tr>
            <td 
              x-text="entry[0]"
            >
              x-bind handler</td>
            <td 
              x-text="entry[1]"
            >$event</td>
            <td 
              x-text="entry[2]"
            >false</td>
          </tr>
        
          <tr>
            <td 
              x-text="entry[0]"
            >
              x-bind handler</td>
            <td 
              x-text="entry[1]"
            >$dispatch</td>
            <td 
              x-text="entry[2]"
            >false</td>
          </tr>
        
          <tr>
            <td 
              x-text="entry[0]"
            >
              x-bind handler</td>
            <td 
              x-text="entry[1]"
            >$nextTick</td>
            <td 
              x-text="entry[2]"
            >true</td>
          </tr>
        
          <tr>
            <td 
              x-text="entry[0]"
            >
              x-bind handler</td>
            <td 
              x-text="entry[1]"
            >$watch</td>
            <td 
              x-text="entry[2]"
            >true</td>
          </tr>
        
          <tr>
            <td 
              x-text="entry[0]"
            >
              x-show handler</td>
            <td 
              x-text="entry[1]"
            >$el</td>
            <td 
              x-text="entry[2]"
            >true</td>
          </tr>
        
          <tr>
            <td 
              x-text="entry[0]"
            >
              x-show handler</td>
            <td 
              x-text="entry[1]"
            >$refs</td>
            <td 
              x-text="entry[2]"
            >true</td>
          </tr>
        
          <tr>
            <td 
              x-text="entry[0]"
            >
              x-show handler</td>
            <td 
              x-text="entry[1]"
            >$event</td>
            <td 
              x-text="entry[2]"
            >false</td>
          </tr>
        
          <tr>
            <td 
              x-text="entry[0]"
            >
              x-show handler</td>
            <td 
              x-text="entry[1]"
            >$dispatch</td>
            <td 
              x-text="entry[2]"
            >false</td>
          </tr>
        
          <tr>
            <td 
              x-text="entry[0]"
            >
              x-show handler</td>
            <td 
              x-text="entry[1]"
            >$nextTick</td>
            <td 
              x-text="entry[2]"
            >true</td>
          </tr>
        
          <tr>
            <td 
              x-text="entry[0]"
            >
              x-show handler</td>
            <td 
              x-text="entry[1]"
            >$watch</td>
            <td 
              x-text="entry[2]"
            >true</td>
          </tr>
        </tbody>
    </table>
  </div>
  <script type="text/javascript">
    const magicProperties = [
      "$el",
      "$refs",
      "$event",
      "$dispatch",
      "$nextTick",
      "$watch",
    ];
    const needsCheck = (hook, table) => {
      return !table.some((el) => el[0].includes(hook));
    };
    function controller() {
      return {
        table: magicProperties.map((p) => {
          return ["x-data", p, Boolean(this[p])];
        }),
        init() {
          if (needsCheck("x-init", this.table)) {
            magicProperties.forEach((p) => {
              this.table.push(["x-init", p, Boolean(this[p])]);
            });
          }
        },
        test() {
          if (needsCheck("x-on", this.table)) {
            magicProperties.forEach((p) => {
              this.table.push(["x-on handler", p, Boolean(this[p])]);
            });
          }
        },
        text() {
          if (needsCheck("x-text", this.table)) {
            magicProperties.forEach((p) => {
              this.table.push(["x-text handler", p, Boolean(this[p])]);
            });
          }
          return "";
        },
        html() {
          if (needsCheck("x-html", this.table)) {
            magicProperties.forEach((p) => {
              this.table.push(["x-html handler", p, Boolean(this[p])]);
            });
          }
          return "";
        },
        bind() {
          if (needsCheck("x-bind", this.table)) {
            magicProperties.forEach((p) => {
              this.table.push(["x-bind handler", p, Boolean(this[p])]);
            });
          }
          return "";
        },
        show() {
          if (needsCheck("x-show", this.table)) {
            magicProperties.forEach((p) => {
              this.table.push(["x-show handler", p, Boolean(this[p])]);
            });
          }
          return "";
        },
      };
    }
  </script>
</div>

💥 Subscribe for Early Access to the Alpine.js Handbook 📖 💥