Skip to content

Commit

Permalink
feat(refs): unbind refs when parent is unbound
Browse files Browse the repository at this point in the history
  • Loading branch information
posva committed Dec 13, 2017
1 parent c2b8991 commit 13a1f8c
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 9 deletions.
20 changes: 17 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ function updateDataFromDocumentSnapshot ({ snapshot, obj, key, subs, depth = 0,
obj: obj[key],
key: refKey,
depth: depth + 1,
// TODO parentSubs
resolve
}),
path: ref.path
Expand All @@ -76,7 +77,14 @@ function subscribeToDocument ({ ref, obj, key, depth, resolve }) {
const subs = Object.create(null)
return ref.onSnapshot(doc => {
if (doc.exists) {
updateDataFromDocumentSnapshot({ snapshot: createSnapshot(doc), obj, key, subs, depth, resolve })
updateDataFromDocumentSnapshot({
snapshot: createSnapshot(doc),
obj,
key,
subs,
depth,
resolve
})
} else {
obj[key] = null
resolve()
Expand All @@ -98,7 +106,7 @@ function bindDocument ({
// bind here the function so it can be resolve anywhere
// this is specially useful for refs
resolve = callOnceWithArg(resolve, () => vm[key])
return document.onSnapshot(doc => {
const unbind = document.onSnapshot(doc => {
if (doc.exists) {
updateDataFromDocumentSnapshot({
snapshot: createSnapshot(doc),
Expand All @@ -110,10 +118,16 @@ function bindDocument ({
} else {
resolve()
}
// TODO resolve when does not exist ?
}, reject)

// TODO return a custom unbind function that unbind all refs
return () => {
unbind()
for (const subKey in subs) {
const sub = subs[subKey]
sub.unbind()
}
}
}

function bind ({ vm, key, ref }) {
Expand Down
43 changes: 37 additions & 6 deletions test/refs.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ beforeEach(async () => {
b = db.collection().doc()
c = collection.doc()
d = collection.doc()
await c.update({ foo: 'foo' })
await c.update({ c: true })
await d.update({ ref: c })

vm = new Vue({
Expand Down Expand Up @@ -63,15 +63,15 @@ test('binds refs on documents', async () => {
test('update inner ref', async () => {
expect(vm.d).toEqual({
ref: {
foo: 'foo'
c: true
}
})

await c.update({ foo: 'bar' })
await c.update({ c: false })

expect(vm.d).toEqual({
ref: {
foo: 'bar'
c: false
}
})
})
Expand All @@ -95,8 +95,7 @@ test('unbinds previously bound document when overwriting a bound', async () => {
c.onSnapshot = jest.fn(fn => onSnapshot((...args) => {
spy()
fn(...args)
})
)
}))
await c.update({ baz: 'baz' })
await d.update({ ref: c })
await delay(5)
Expand Down Expand Up @@ -155,3 +154,35 @@ test('resolves the promise when the document does not exist', async () => {
await vm.$bind('item', a)
expect(vm.item).toBe(null)
})

function spyUnbind (ref) {
const spy = jest.fn()
const onSnapshot = ref.onSnapshot.bind(ref)
ref.onSnapshot = jest.fn(fn => {
const unbind = onSnapshot(fn)
return () => {
spy()
unbind()
}
})
return spy
}

test('unbinds all refs when the document is unbound', async () => {
const cSpy = spyUnbind(c)
const dSpy = spyUnbind(d)
// rebind to use the spies
await vm.$bind('d', d)
expect(vm.d).toEqual({
ref: {
c: true
}
})
vm.$unbind('d')

expect(dSpy.mock.calls.length).toBe(1)
expect(cSpy.mock.calls.length).toBe(1)

cSpy.mockRestore()
dSpy.mockRestore()
})

0 comments on commit 13a1f8c

Please sign in to comment.