Skip to content

Commit

Permalink
🐛 Fixes issue with setters accessing deeply nested data (#4265)
Browse files Browse the repository at this point in the history
  • Loading branch information
ekwoka authored Jun 15, 2024
1 parent 1927cb1 commit 541cb8e
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 1 deletion.
3 changes: 2 additions & 1 deletion packages/alpinejs/src/scope.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ let mergeProxyTrap = {
) || objects[objects.length - 1];
const descriptor = Object.getOwnPropertyDescriptor(target, name);
if (descriptor?.set && descriptor?.get)
return Reflect.set(target, name, value, thisProxy);
// Can't use Reflect.set here due to [upstream bug](https://github.com/vuejs/core/blob/31abdc8adad569d83b476c340e678c4daa901545/packages/reactivity/src/baseHandlers.ts#L148) in @vue/reactivity
return descriptor.set.call(thisProxy, value) || true;
return Reflect.set(target, name, value);
},
}
Expand Down
48 changes: 48 additions & 0 deletions tests/cypress/integration/scope.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,51 @@ test(
get("button").should(haveText("clicked"));
}
);

test(
"properly merges the datastack with nested data",
[
html`
<div x-data="{ foo: { bar: 'fizz' } }">
<div x-data="{ bar: 'buzz' }">
<span
id="1"
x-text="foo.bar + bar"
@click="foo.bar = foo.bar + bar"
></span>
</div>
<span id="2" x-text="foo.bar"></span>
</div>
`,
],
({ get }) => {
get("span#1").should(haveText("fizzbuzz"));
get("span#2").should(haveText("fizz"));
get("span#1").click();
get("span#1").should(haveText("fizzbuzzbuzz"));
get("span#2").should(haveText("fizzbuzz"));
}
);

test(
"handles getter setter pairs of object",
[
html`
<div x-data="{ foo: { bar: 'fizzbuzz' } }">
<div
x-data="{ get bar() { return this.foo.bar }, set bar(value) { this.foo.bar = value } }"
>
<span id="one" x-text="bar" @click="bar = 'foobar'"></span>
</div>
<span id="two" x-text="foo.bar"></span>
</div>
`,
],
({ get }) => {
get("span#one").should(haveText("fizzbuzz"));
get("span#two").should(haveText("fizzbuzz"));
get("span#one").click();
get("span#one").should(haveText("foobar"));
get("span#two").should(haveText("foobar"));
}
);

0 comments on commit 541cb8e

Please sign in to comment.