Skip to content

Commit b6bfe5e

Browse files
committed
fix: Make sure mutations target the receiver proxy observed by Vue
GenericModel's methods like $get where mutating the internal #proxy object which meant Vue could not observe these changes. By binding GenericModel's methods to the receiver instance and mutating these directly Vue can pick up on these changes. This reflects the behavior of GenericCollection. Resolves #727
1 parent 29a20d9 commit b6bfe5e

File tree

2 files changed

+24
-21
lines changed

2 files changed

+24
-21
lines changed

src/GenericModel.js

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@ class GenericModel {
2020
},
2121
get: (target, propertyKey, receiver) => {
2222
if (propertyKey === 'constructor' || Reflect.ownKeys(this).includes(propertyKey)) {
23-
return Reflect.get(this, propertyKey, this)
23+
const val = Reflect.get(this, propertyKey, this)
24+
if (['$get', '$post', '$put', '$patch', '$delete'].includes(propertyKey)) {
25+
return val.bind(this, receiver)
26+
}
27+
return val
2428
}
2529
return Reflect.get(target, propertyKey, receiver)
2630
},
@@ -34,7 +38,7 @@ class GenericModel {
3438
})
3539
}
3640

37-
async #request ({ method, keepChanges = false, needsQuery = true }, signal, opts, ...data) {
41+
async #request (receiver, { method, keepChanges = false, needsQuery = true }, signal, opts, ...data) {
3842
await this.#options.route.$ready
3943
const { columns, ...options } = opts
4044

@@ -79,32 +83,32 @@ class GenericModel {
7983
// TODO: do we need to delete missing keys?
8084
if (keepChanges) {
8185
const diff = this.#proxy[$diff]
82-
Object.entries(body).forEach(([key, value]) => { this.#proxy[key] = value })
86+
Object.entries(body).forEach(([key, value]) => { receiver[key] = value })
8387
this.#proxy[$freeze]()
84-
Object.entries(diff).forEach(([key, value]) => { this.#proxy[key] = value })
88+
Object.entries(diff).forEach(([key, value]) => { receiver[key] = value })
8589
} else {
86-
Object.entries(body).forEach(([key, value]) => { this.#proxy[key] = value })
90+
Object.entries(body).forEach(([key, value]) => { receiver[key] = value })
8791
this.#proxy[$freeze]()
8892
}
8993
return body
9094
}
9195

92-
$get = new ObservableFunction(async (signal, opts = {}) => {
96+
$get = new ObservableFunction(async (receiver, signal, opts = {}) => {
9397
const { keepChanges, ...options } = opts
94-
return this.#request({ method: 'get', keepChanges }, signal, options)
98+
return this.#request(receiver, { method: 'get', keepChanges }, signal, options)
9599
})
96100

97-
$post = new ObservableFunction(async (signal, opts = {}) => {
101+
$post = new ObservableFunction(async (receiver, signal, opts = {}) => {
98102
const options = { return: 'representation', ...opts }
99-
return this.#request({ method: 'post', needsQuery: false }, signal, options, this.#proxy)
103+
return this.#request(receiver, { method: 'post', needsQuery: false }, signal, options, this.#proxy)
100104
})
101105

102-
$put = new ObservableFunction(async (signal, opts) => {
106+
$put = new ObservableFunction(async (receiver, signal, opts) => {
103107
const options = { return: 'representation', ...opts }
104-
return this.#request({ method: 'put' }, signal, options, this.#proxy)
108+
return this.#request(receiver, { method: 'put' }, signal, options, this.#proxy)
105109
})
106110

107-
$patch = new ObservableFunction(async (signal, opts, data = {}) => {
111+
$patch = new ObservableFunction(async (receiver, signal, opts, data = {}) => {
108112
const options = { return: 'representation', ...opts }
109113

110114
if (!data || typeof data !== 'object') {
@@ -121,11 +125,11 @@ class GenericModel {
121125
return this.#proxy
122126
}
123127

124-
return this.#request({ method: 'patch' }, signal, options, patchData)
128+
return this.#request(receiver, { method: 'patch' }, signal, options, patchData)
125129
})
126130

127-
$delete = new ObservableFunction(async (signal, options = {}) => {
128-
return this.#request({ method: 'delete' }, signal, options)
131+
$delete = new ObservableFunction(async (receiver, signal, options = {}) => {
132+
return this.#request(receiver, { method: 'delete' }, signal, options)
129133
})
130134
}
131135

tests/unit/mixin.spec.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -365,12 +365,11 @@ describe('Mixin', () => {
365365

366366
expect(wrapper.vm.pg).toEqual({ id: 1, name: 'Test Client 1' })
367367
expect(wrapper.html()).toMatchInlineSnapshot(`
368-
"<pre>{
369-
"id": 1,
370-
"name": "Test Client 1"
371-
}
372-
</pre>"
373-
`)
368+
"<pre>{
369+
"id": 1,
370+
"name": "Test Client 1"
371+
}</pre>"
372+
`)
374373
})
375374
})
376375
})

0 commit comments

Comments
 (0)