Skip to content

Commit 603f2b8

Browse files
committed
refactor: move temp to keyedById in updateTemp. No longer need tempsByNewId
1 parent 0298f6d commit 603f2b8

File tree

7 files changed

+55
-67
lines changed

7 files changed

+55
-67
lines changed

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

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,6 @@ export default function makeServiceActions(service: Service<any>) {
312312
addOrUpdate({ state, commit }, item) {
313313
const { idField } = state
314314
const id = getId(item, idField)
315-
const existingItem = state.keyedById[id]
316315

317316
const isIdOk = id !== null && id !== undefined
318317

@@ -323,22 +322,14 @@ export default function makeServiceActions(service: Service<any>) {
323322
item = new service.FeathersVuexModel(item, { commit: false })
324323
}
325324

326-
// If the item has a matching temp, update the temp and provide it as the new item.
327-
const temp = state.tempsByNewId[id]
328-
if (temp) {
329-
commit('merge', { dest: temp, source: item })
330-
commit('remove__isTemp', temp)
331-
}
332325
if (isIdOk) {
333-
if (existingItem && temp) {
334-
commit('replaceItemWithTemp', { item, temp })
326+
if (state.keyedById[id]) {
327+
commit('updateItem', item)
335328
} else {
336-
existingItem
337-
? commit('updateItem', temp || item)
338-
: commit('addItem', temp || item)
329+
commit('addItem', item)
339330
}
340331
}
341-
return temp || item
332+
return item
342333
}
343334
}
344335
/**

src/service-module/service-module.getters.ts

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import { filterQuery, sorter, select } from '@feathersjs/adapter-commons'
99
import { globalModels as models } from './global-models'
1010
import _get from 'lodash/get'
1111
import _omit from 'lodash/omit'
12-
import _unionBy from 'lodash/unionBy'
1312

1413
const FILTERS = ['$sort', '$limit', '$skip', '$select']
1514
const OPERATORS = ['$in', '$nin', '$lt', '$lte', '$gt', '$gte', '$ne', '$or']
@@ -27,7 +26,7 @@ export default function makeServiceGetters() {
2726
// Set params.temps to true to include the tempsById records
2827
params.temps = params.hasOwnProperty('temps') ? params.temps : false
2928

30-
const { paramsForServer, whitelist, idField, tempIdField } = state
29+
const { paramsForServer, whitelist, keyedById } = state
3130
const q = _omit(params.query || {}, paramsForServer)
3231
const customOperators = Object.keys(q).filter(
3332
k => k[0] === '$' && !defaultOps.includes(k)
@@ -37,14 +36,10 @@ export default function makeServiceGetters() {
3736
const { query, filters } = filterQuery(cleanQuery, {
3837
operators: additionalOperators.concat(whitelist)
3938
})
40-
let values = _.values(state.keyedById)
39+
let values = _.values(keyedById)
4140

4241
if (params.temps) {
43-
values = _unionBy(
44-
values,
45-
_.values(state.tempsById),
46-
i => i[tempIdField] || i[idField]
47-
)
42+
values = values.concat(_.values(state.tempsById))
4843
}
4944

5045
values = values.filter(sift(query))

src/service-module/service-module.mutations.ts

Lines changed: 10 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -142,9 +142,13 @@ export default function makeServiceMutations() {
142142
// can migrate the temp to the keyedById state.
143143
updateTemp(state, { id, tempId }) {
144144
const temp = state.tempsById[tempId]
145-
if (state.tempsById) {
145+
if (temp) {
146146
temp[state.idField] = id
147-
state.tempsByNewId[id] = temp
147+
Vue.delete(temp, '__isTemp')
148+
Vue.delete(state.tempsById, tempId)
149+
// If an item already exists in the store from the `created` event firing
150+
// it will be replaced here
151+
Vue.set(state.keyedById, id, temp)
148152
}
149153

150154
// Add _id to temp's clone as well if it exists
@@ -153,32 +157,7 @@ export default function makeServiceMutations() {
153157
if (tempClone) {
154158
tempClone[state.idField] = id
155159
Model.copiesById[id] = tempClone
156-
}
157-
},
158-
159-
/**
160-
* Overwrites the item with matching id with the temp record.
161-
* This is to preserve reactivity for temp records.
162-
*/
163-
replaceItemWithTemp(state, { item, temp }) {
164-
const id = item[state.idField]
165-
if (state.keyedById[id]) {
166-
state.keyedById[id] = temp
167-
Vue.delete(state.keyedById[id], '__isTemp')
168-
}
169-
},
170-
171-
remove__isTemp({ modelName, serverAlias, tempIdField }, temp) {
172-
Vue.delete(temp, '__isTemp')
173-
174-
// Remove from temp's clone as well if it exists
175-
const tempId = temp[tempIdField]
176-
if (tempId) {
177-
const Model = _get(models, `[${serverAlias}][${modelName}]`)
178-
const tempClone = Model && Model.copiesById && Model.copiesById[tempId]
179-
if (tempClone) {
180-
Vue.delete(tempClone, '__isTemp')
181-
}
160+
Vue.delete(tempClone, '__isTemp')
182161
}
183162
},
184163

@@ -194,24 +173,18 @@ export default function makeServiceMutations() {
194173
}
195174
},
196175

197-
// Removes temp records. Also cleans up tempsByNewId
176+
// Removes temp records
198177
removeTemps(state, tempIds) {
199-
const ids = tempIds.reduce((ids, id) => {
178+
tempIds.forEach(id => {
200179
const temp = state.tempsById[id]
201180
if (temp) {
202181
if (temp[state.idField]) {
203182
// Removes __isTemp if created
204183
delete temp.__isTemp
205184
Vue.delete(temp, '__isTemp')
206-
ids.push(temp[state.idField])
207-
} else {
208-
// Removes uncreated temp
209-
ids.push(temp[state.tempIdField])
210185
}
211186
}
212-
return ids
213-
}, [])
214-
state.tempsByNewId = _omit(state.tempsByNewId, ids)
187+
})
215188
state.tempsById = _omit(state.tempsById, tempIds)
216189
},
217190

src/service-module/service-module.state.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ export interface ServiceStateExclusiveDefaults {
2727

2828
keyedById: {}
2929
tempsById: {}
30-
tempsByNewId: {}
3130
copiesById: {}
3231
namespace?: string
3332
pagination?: {
@@ -57,7 +56,6 @@ export interface ServiceState {
5756
idField: string
5857
keyedById: {}
5958
tempsById: {}
60-
tempsByNewId: {}
6159
copiesById: {}
6260
whitelist: string[]
6361
paramsForServer: string[]
@@ -98,7 +96,6 @@ export default function makeDefaultState(options: MakeServicePluginOptions) {
9896
keyedById: {},
9997
copiesById: {},
10098
tempsById: {}, // Really should be called tempsByTempId
101-
tempsByNewId: {}, // temporary storage for temps while getting transferred from tempsById to keyedById
10299
pagination: {
103100
defaultLimit: null,
104101
defaultSkip: null

test/service-module/make-service-plugin.test.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ describe('makeServicePlugin', function() {
8787
servicePath: 'todos',
8888
skipRequestIfExists: false,
8989
tempsById: {},
90-
tempsByNewId: {},
9190
whitelist: []
9291
}
9392

test/service-module/model-temp-ids.test.ts

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import Vue from 'vue/dist/vue'
1313
import Vuex from 'vuex'
1414
import { makeStore } from '../test-utils'
1515
import ObjectID from 'bson-objectid'
16+
import fastCopy from 'fast-copy'
1617

1718
interface RootState {
1819
transactions: ServiceState
@@ -211,8 +212,6 @@ describe('Models - Temp Ids', function() {
211212
assert(response._id === 1)
212213
assert(response.__id, 'the temp id is still intact')
213214
assert(!store.state.things.tempsById[response.__id])
214-
//@ts-ignore
215-
assert(!Object.keys(store.state.things.tempsByNewId).length)
216215
assert(response === thing, 'maintained the reference')
217216
})
218217
})
@@ -401,12 +400,43 @@ describe('Models - Temp Ids', function() {
401400
const clone = thing.clone()
402401
assert(clone.__isTemp, 'Clone also has __isTemp')
403402

404-
store.commit('things/remove__isTemp', thing)
403+
store.commit('things/updateTemp', { id: 42, tempId: thing.__id })
405404

406405
assert(!thing.hasOwnProperty('__isTemp'), '__isTemp was removed from thing')
407406
assert(!clone.hasOwnProperty('__isTemp'), '__isTemp was removed from clone')
408407
})
409408

409+
it('updateTemp assigns ID to temp and migrates it from tempsById to keyedById', function() {
410+
const { makeServicePlugin, BaseModel } = feathersVuex(feathersClient, {
411+
idField: '_id',
412+
serverAlias: 'temp-ids'
413+
})
414+
class Thing extends BaseModel {
415+
public static modelName = 'Thing'
416+
}
417+
const store = new Vuex.Store<RootState>({
418+
plugins: [
419+
makeServicePlugin({
420+
Model: Thing,
421+
service: feathersClient.service('things')
422+
})
423+
]
424+
})
425+
426+
const thing = new Thing()
427+
assert(thing.__id, 'thing has tempId')
428+
assert(!thing._id, 'thing does not have _id')
429+
assert(store.state.things.tempsById[thing.__id], 'thing is in tempsById')
430+
431+
store.commit('things/updateTemp', { id: 42, tempId: thing.__id })
432+
assert(thing._id === 42, 'thing got _id')
433+
assert(store.state.things.keyedById[42] === thing, 'thing is in keyedById')
434+
assert(
435+
!store.state.things.tempsById[thing.__id],
436+
'thing is no longer in tempsById'
437+
)
438+
})
439+
410440
it('Clone gets _id after save (create only called once)', async function() {
411441
// Test ensures subsequent calls to clone.save() do not call create
412442
const { makeServicePlugin, BaseModel } = feathersVuex(feathersClient, {
@@ -504,6 +534,10 @@ describe('Models - Temp Ids', function() {
504534
feathersClient.service('foos').hooks({
505535
before: {
506536
create: [
537+
context => {
538+
delete context.data.__id
539+
delete context.data.__isTemp
540+
},
507541
context => {
508542
context.result = { _id: 24, ...context.data }
509543
return context
@@ -526,7 +560,7 @@ describe('Models - Temp Ids', function() {
526560
},
527561
watch: {
528562
things(items) {
529-
watchEvents.push(items)
563+
watchEvents.push(fastCopy(items))
530564
}
531565
}
532566
}).$mount()

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,6 @@ describe('Service Module', function() {
658658
servicePath: 'service-todos',
659659
tempIdField: '__id',
660660
tempsById: {},
661-
tempsByNewId: {},
662661
pagination: {
663662
defaultLimit: null,
664663
defaultSkip: null

0 commit comments

Comments
 (0)