Browse Source

Fix `x-init` bug introduced in v3.3.0 (#2028)

* refactor: fix `x-init` bug

### Bug caused by #1993

The change breaks `x-init` expressions that are defined via `x-bind` and possibly other
directives that pass an object through. It assumes the value of `x-init` will always be a string
(empty or not) by using the `trim` function.

The following still works after this change:

```
<div x-init="$nextTick(() => { console.log('this works') })"></div>
```

But the following will now break:

```
<script>
const test = {
  ['x-init']() {
    return this.$nextTick(() => console.log('this will not be logged'));
  }
};
</script>

<div x-bind="test"></div>
```

### Change introduced to fix

Check the `expression` is a string before checking `trim` produces an empty string.

* fix: fix failed test

The original change also defeated the purpose of the empty `x-init` change in #1993 since it was evaluated right away before checking type.
Matthew Martindale 3 years ago
parent
commit
55dea75ca4
1 changed files with 7 additions and 1 deletions
  1. 7 1
      packages/alpinejs/src/directives/x-init.js

+ 7 - 1
packages/alpinejs/src/directives/x-init.js

@@ -5,4 +5,10 @@ import { evaluate } from "../evaluator";
 
 addInitSelector(() => `[${prefix('init')}]`)
 
-directive('init', skipDuringClone((el, { expression }) => !! expression.trim() && evaluate(el, expression, {}, false)))
+directive('init', skipDuringClone((el, { expression }) => {
+  if (typeof expression === 'string') {
+    return !! expression.trim() && evaluate(el, expression, {}, false)
+  }
+
+  return evaluate(el, expression, {}, false)
+}))