Skip to content

Commit 5079a35

Browse files
committed
feat(refs): unbind removed refs on documents
1 parent 7abe7d6 commit 5079a35

File tree

3 files changed

+61
-0
lines changed

3 files changed

+61
-0
lines changed

src/index.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ function subscribeToRefs ({
1313
resolve
1414
}) {
1515
const refKeys = Object.keys(refs)
16+
const missingKeys = Object.keys(subs).filter(refKey => refKeys.indexOf(refKey) < 0)
17+
// unbind keys that are no longer there
18+
missingKeys.forEach(refKey => {
19+
subs[refKey].unbind()
20+
delete subs[refKey]
21+
})
1622
if (!refKeys.length) return resolve()
1723
// TODO check if no ref is missing
1824
// TODO max depth param, default to 1?
@@ -92,6 +98,8 @@ function bindCollection ({
9298
array.splice(oldIndex, 1)
9399
array.splice(newIndex, 0, createSnapshot(doc))
94100
// TODO replace listeners of nested refs
101+
const subs = arraySubs.splice(oldIndex, 1)[0]
102+
arraySubs.splice(newIndex, 0, subs)
95103
},
96104
removed: ({ oldIndex }) => {
97105
array.splice(oldIndex, 1)

test/helpers/mock.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,13 @@ export class DocumentReference {
7171
this.cb(new DocumentSnapshot(null, this.id, this.data, true))
7272
return this.collection._modify(this.id, this.data)
7373
}
74+
75+
async set (data) {
76+
this.data = { ...data }
77+
this.exists = true
78+
this.cb(new DocumentSnapshot(null, this.id, this.data, true))
79+
return this.collection._modify(this.id, this.data)
80+
}
7481
}
7582

7683
class CollectionReference {

test/refs-documents.spec.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,3 +309,49 @@ test('unbinds when a ref is replaced', async () => {
309309
cSpy.mockRestore()
310310
dSpy.mockRestore()
311311
})
312+
313+
test('unbinds removed properties', async () => {
314+
const a = db.collection().doc()
315+
const b = db.collection().doc()
316+
const unbindSpy = spyUnbind(a)
317+
const callbackSpy = spyOnSnapshotCallback(a)
318+
const onSnapshotSpy = spyOnSnapshot(a)
319+
320+
const item = db.collection().doc()
321+
await a.update({ isA: true })
322+
await b.update({ isB: true })
323+
await item.update({ a })
324+
325+
expect(unbindSpy).toHaveBeenCalledTimes(0)
326+
expect(callbackSpy).toHaveBeenCalledTimes(0)
327+
expect(onSnapshotSpy).toHaveBeenCalledTimes(0)
328+
await vm.$bind('item', item)
329+
expect(vm.item).toEqual({
330+
a: {
331+
isA: true
332+
}
333+
})
334+
335+
expect(unbindSpy).toHaveBeenCalledTimes(0)
336+
expect(callbackSpy).toHaveBeenCalledTimes(1)
337+
expect(onSnapshotSpy).toHaveBeenCalledTimes(1)
338+
339+
await item.set({ b })
340+
await a.update({ newA: true })
341+
// NOTE see #1
342+
await delay(5)
343+
344+
expect(vm.item).toEqual({
345+
b: {
346+
isB: true
347+
}
348+
})
349+
350+
expect(unbindSpy).toHaveBeenCalledTimes(1)
351+
expect(callbackSpy).toHaveBeenCalledTimes(1)
352+
expect(onSnapshotSpy).toHaveBeenCalledTimes(1)
353+
354+
unbindSpy.mockRestore()
355+
callbackSpy.mockRestore()
356+
onSnapshotSpy.mockRestore()
357+
})

0 commit comments

Comments
 (0)