Skip to content

Commit cb1ab88

Browse files
committed
fix(refs): resolve the promise when all resolve are called
1 parent 1029c92 commit cb1ab88

File tree

2 files changed

+120
-4
lines changed

2 files changed

+120
-4
lines changed

src/index.js

+16-4
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,25 @@ function subscribeToRefs ({
2525
subs[refKey].unsub()
2626
delete subs[refKey]
2727
})
28-
if (!refKeys.length) return resolve()
28+
if (!refKeys.length) return resolve(path)
2929
// TODO max depth param, default to 1?
3030
if (++depth > 3) throw new Error('more than 5 nested refs')
3131

32+
let resolvedCount = 0
33+
const totalToResolve = refKeys.length
34+
const validResolves = Object.create(null)
35+
function deepResolve (key) {
36+
if (key in validResolves) {
37+
if (++resolvedCount >= totalToResolve) resolve(path)
38+
}
39+
}
40+
3241
refKeys.forEach(refKey => {
3342
const sub = subs[refKey]
3443
const ref = refs[refKey]
44+
const docPath = `${path}.${refKey}`
45+
46+
validResolves[docPath] = true
3547

3648
// unsubscribe if bound to a different ref
3749
if (sub) {
@@ -44,9 +56,9 @@ function subscribeToRefs ({
4456
unsub: subscribeToDocument({
4557
ref,
4658
target,
47-
path: `${path}.${refKey}`,
59+
path: docPath,
4860
depth,
49-
resolve
61+
resolve: deepResolve.bind(null, docPath)
5062
}),
5163
path: ref.path
5264
}
@@ -177,7 +189,7 @@ function subscribeToDocument ({ ref, target, path, depth, resolve }) {
177189
})
178190
} else {
179191
walkSet(target, path, null)
180-
resolve()
192+
resolve(path)
181193
}
182194
})
183195

test/bind.spec.js

+104
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import Vuefire from '../src'
22
import {
33
db,
44
tick,
5+
delayUpdate,
56
Vue
67
} from './helpers'
78

@@ -84,3 +85,106 @@ test('unbinds previously bound refs', async () => {
8485
expect(vm.$firestoreRefs.item).toBe(doc2)
8586
expect(vm.item).toEqual({ bar: 'bar' })
8687
})
88+
89+
test('waits for all refs in document', async () => {
90+
const a = db.collection().doc()
91+
const b = db.collection().doc()
92+
delayUpdate(b)
93+
await document.update({ a, b })
94+
95+
await vm.$bind('item', document)
96+
97+
expect(vm.item).toEqual({
98+
a: null,
99+
b: null
100+
})
101+
})
102+
103+
test('waits for all refs in collection', async () => {
104+
const a = db.collection().doc()
105+
const b = db.collection().doc()
106+
delayUpdate(b)
107+
await collection.add({ a })
108+
await collection.add({ b })
109+
110+
await vm.$bind('items', collection)
111+
112+
expect(vm.items).toEqual([
113+
{ a: null },
114+
{ b: null }
115+
])
116+
})
117+
118+
test('waits for nested refs in document', async () => {
119+
const a = db.collection().doc()
120+
const b = db.collection().doc()
121+
const c = db.collection().doc()
122+
await b.update({ c })
123+
delayUpdate(b)
124+
delayUpdate(c, 5)
125+
await document.update({ a, b })
126+
127+
await vm.$bind('item', document)
128+
129+
expect(vm.item).toEqual({
130+
a: null,
131+
b: { c: null }
132+
})
133+
})
134+
135+
test('waits for nested refs with data in document', async () => {
136+
const a = db.collection().doc()
137+
const b = db.collection().doc()
138+
const c = db.collection().doc()
139+
await a.update({ isA: true })
140+
await c.update({ isC: true })
141+
await b.update({ c })
142+
delayUpdate(b)
143+
delayUpdate(c, 5)
144+
await document.update({ a, b })
145+
146+
await vm.$bind('item', document)
147+
148+
expect(vm.item).toEqual({
149+
a: { isA: true },
150+
b: { c: { isC: true }}
151+
})
152+
})
153+
154+
test('waits for nested refs in collections', async () => {
155+
const a = db.collection().doc()
156+
const b = db.collection().doc()
157+
const c = db.collection().doc()
158+
await b.update({ c })
159+
delayUpdate(b)
160+
delayUpdate(c, 5)
161+
await collection.add({ a })
162+
await collection.add({ b })
163+
164+
await vm.$bind('items', collection)
165+
166+
expect(vm.items).toEqual([
167+
{ a: null },
168+
{ b: { c: null }}
169+
])
170+
})
171+
172+
test('waits for nested refs with data in collections', async () => {
173+
const a = db.collection().doc()
174+
const b = db.collection().doc()
175+
const c = db.collection().doc()
176+
await a.update({ isA: true })
177+
await c.update({ isC: true })
178+
await b.update({ c })
179+
delayUpdate(b)
180+
delayUpdate(c, 5)
181+
await collection.add({ a })
182+
await collection.add({ b })
183+
184+
await vm.$bind('items', collection)
185+
186+
expect(vm.items).toEqual([
187+
{ a: { isA: true }},
188+
{ b: { c: { isC: true }}}
189+
])
190+
})

0 commit comments

Comments
 (0)