Skip to content

Commit dfbe06d

Browse files
committed
feat: allow partial patching with params.data
## Partial data on patch As of version 3.9.0, you can provide an object as `params.data`, and Feathers-Vuex will use `params.data` as the patch data. This change was made to the service-module, itself, so it will work for `patch` across all of feathers-vuex. Here's an example of patching with partial data: ```js import { models } from 'feathers-vuex' const { Todo } = models.api const todo = new Todo({ description: 'Do Something', isComplete: false }) todo.patch({ data: { isComplete: true } }) // also works for patching with instance.save todo.save({ data: { isComplete: true } }) ```
1 parent f22c45e commit dfbe06d

File tree

6 files changed

+75
-3
lines changed

6 files changed

+75
-3
lines changed

docs/2.0-major-release.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,8 @@ I have not been able to find a diffing algorithm that works equally well acroos
163163

164164
## Model Classes: BYOD (Bring Your Own Diffing)
165165

166+
> Note: As of `[email protected]`, you can also pass `params.data` to the patch object to implement partial patching on objects. You might choose to use `params.data` instead of `diffOnPatch`.
167+
166168
First, why do any diffing? On the API server, an `update` request replaces an entire object, but a `patch` request only overwrites the attributes that are provided in the data. For services with simple schemas, it doesn't really matter. But if your schema grows really large, it can be supportive to only send the updates instead of the entire object.
167169

168170
A new `diffOnPatch` method is available to override in your extended models. `diffOnPatch` gets called just before sending the data to the API server. It gets called with the data and must return the diffed data. By default, it is set to `diffOnPatch: data => data`.

docs/3.0-major-release.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,21 @@ Version 3.0 of Feathers-Vuex is the Vue Composition API release! There were qui
1616

1717
And now it has become the best way to perform queries with Feathers-Vuex. To find out how to take advantage of the new functionality in your apps, read the [Feather-Vuex Composition API docs](./composition-api.md).
1818

19+
## Partial data on patch <Badge text="3.9.0+" />
20+
As of version 3.9.0, you can provide an object as `params.data`, and Feathers-Vuex will use `params.data` as the patch data. This change was made to the service-module, itself, so it will work for `patch` across all of feathers-vuex. Here's an example of patching with partial data:
21+
22+
```js
23+
import { models } from 'feathers-vuex'
24+
const { Todo } = models.api
25+
26+
const todo = new Todo({ description: 'Do Something', isComplete: false })
27+
28+
todo.patch({ data: { isComplete: true } })
29+
30+
// also works for patching with instance.save
31+
todo.save({ data: { isComplete: true } })
32+
```
33+
1934
## FeathersVuexPagination Component <Badge text="3.8.0+" />
2035

2136
To assist with Server Side Pagination support, Feathers-Vuex now includes the `<FeathersVuexPagination>` component. It's a renderless component that removes the boilerplate behind handling pagination in the UI. Read about it in the [Composition API Docs](/composition-api.html#feathersvuexpagination).

docs/model-classes.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ The `patch` method calls the `patch` action (service method) using the instance
302302

303303
Similar to the `.create()` method, you might not ever need to use `.patch()` if you just use `.save()` and let `feathers-vuex` figure out how to handle it.
304304

305+
305306
```js
306307
const { Todo } = this.$FeathersVuex.api
307308
const todo = new Todo({ id: 1, description: 'Do something!' })
@@ -311,7 +312,16 @@ todo.description = 'Do something else'
311312
todo.patch() // --> Sends a `patch` request the with the id and description.
312313
```
313314

314-
*Note: Currently, patch sends all data, not just what has changed. In a future update, it will only send the fields that have changed.*
315+
<Badge text="3.9.0+" /> As of version 3.9.0, you can provide an object as `params.data`, and Feathers-Vuex will use `params.data` as the patch data. This allows patching with partial data:
316+
317+
```js
318+
import { models } from 'feathers-vuex'
319+
const { Todo } = models.api
320+
321+
const todo = new Todo({ description: 'Do Something', isComplete: false })
322+
323+
todo.patch({ data: { isComplete: true } })
324+
```
315325

316326
### `instance.update(params)`
317327

docs/service-plugin.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ Patch (merge in changes) one or more records
363363
- `paramArray {Array}` - array containing the three parameters patch takes.
364364
- `id {Number|String}` - the `id` of the existing record being requested from the API server.
365365
- `data {Object}` - the data that will be merged into the existing record
366-
- `params {Object}` - An object containing a `query` object.
366+
- `params {Object}` - An object containing a `query` object. If params.data is provided, it will be used as the patch data, providing a simple way to patch with partial data.
367367

368368
```js
369369
let data = {description: 'write your tests', completed: true}

src/service-module/service-module.actions.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,14 +145,21 @@ export default function makeServiceActions(service) {
145145
})
146146
},
147147

148+
/**
149+
* If params.data is provided, it will be passed as the patch data (instead of the `data` arg).
150+
* This provides a simple way to patch with partial data.
151+
*/
148152
patch({ commit, dispatch, state }, [id, data, params]) {
149153
commit('setPending', 'patch')
150154

151155
params = fastCopy(params)
152156

153-
if (service.FeathersVuexModel) {
157+
if (service.FeathersVuexModel && params && !params.data) {
154158
data = service.FeathersVuexModel.diffOnPatch(data)
155159
}
160+
if (params && params.data) {
161+
data = params.data
162+
}
156163

157164
return service
158165
.patch(id, data, params)

test/service-module/service-module.actions.test.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -995,6 +995,44 @@ describe('Service Module - Actions', () => {
995995
})
996996
})
997997

998+
it('overrides patch data with params.data', done => {
999+
const { makeServicePlugin, Todo } = makeContext()
1000+
const store = new Vuex.Store<RootState>({
1001+
plugins: [
1002+
makeServicePlugin({
1003+
servicePath: 'my-todos',
1004+
Model: Todo,
1005+
service: feathersClient.service('my-todos')
1006+
})
1007+
]
1008+
})
1009+
const actions = mapActions('my-todos', ['create', 'patch'])
1010+
const originalData = { description: 'Do something', test: true }
1011+
1012+
actions.create.call({ $store: store }, originalData).then(() => {
1013+
const data = {
1014+
description:
1015+
'This description should not be patched since params.data is provided'
1016+
}
1017+
const params = { data: { test: false } }
1018+
actions.patch
1019+
.call({ $store: store }, [0, data, params])
1020+
.then(responseFromPatch => {
1021+
assert.equal(
1022+
responseFromPatch.description,
1023+
originalData.description,
1024+
'description should not have changed'
1025+
)
1026+
assert.equal(
1027+
responseFromPatch.test,
1028+
false,
1029+
'Providing params.data should have set the test attribute to false.'
1030+
)
1031+
done()
1032+
})
1033+
})
1034+
})
1035+
9981036
it('updates store state on service success', done => {
9991037
const { makeServicePlugin, Todo } = makeContext()
10001038
const store = new Vuex.Store<RootState>({

0 commit comments

Comments
 (0)