Skip to content

Commit 14a6c55

Browse files
committed
feat(refs): support refs in collection when adding
1 parent 350a08f commit 14a6c55

File tree

5 files changed

+113
-2
lines changed

5 files changed

+113
-2
lines changed

examples/index.html

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,18 @@
4343
</li>
4444
</ul>
4545

46+
<h4>collection with refs</h4>
47+
48+
<ul>
49+
<li v-for="moment in moments">{{ moment }}</li>
50+
</ul>
51+
52+
<h5>Original data</h5>
53+
54+
<ul>
55+
<li v-for="tweet in tweets">{{ tweet }}</li>
56+
</ul>
57+
4658
<p>config: </p>
4759
<pre>
4860
{{ config }}
@@ -66,12 +78,15 @@
6678
el: '#app',
6779
data: {
6880
todos: [],
81+
tweets: [],
6982
config: null,
7083
newTodoText: ''
7184
},
7285

7386
firestore: {
7487
todos: unFinishedTodos,
88+
moments: db.collection('moments'),
89+
tweets: db.collection('tweets'),
7590
config
7691
},
7792

src/index.js

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,58 @@ function bindCollection ({
99
}) {
1010
// TODO wait to get all data
1111
const array = vm[key] = []
12+
const depth = 0
1213

1314
const change = {
1415
added: ({ newIndex, doc }) => {
15-
array.splice(newIndex, 0, createSnapshot(doc))
16+
const subs = {}
17+
const snapshot = createSnapshot(doc)
18+
const [data, refs] = extractRefs(snapshot)
19+
array.splice(newIndex, 0, data)
20+
const refKeys = Object.keys(refs)
21+
if (!refKeys.length) return // resolve()
22+
// TODO check if no ref is missing
23+
// TODO max depth param, default to 1?
24+
// if (++depth > 3) throw new Error('more than 5 nested refs')
25+
refKeys.forEach(refKey => {
26+
// check if already bound to the same ref -> skip
27+
const sub = subs[refKey]
28+
const ref = refs[refKey]
29+
if (sub && sub.path !== ref.path) {
30+
sub.unbind()
31+
}
32+
// maybe wrap the unbind function to call unbind on every child
33+
const [innerObj, innerKey] = deepGetSplit(array[newIndex], refKey)
34+
if (!innerObj) {
35+
console.log('=== ERROR ===')
36+
console.log(data, refKey, newIndex, innerObj, innerKey)
37+
console.log('===')
38+
}
39+
subs[refKey] = {
40+
unbind: subscribeToDocument({
41+
ref,
42+
obj: innerObj,
43+
key: innerKey,
44+
depth,
45+
// TODO parentSubs
46+
resolve
47+
}),
48+
path: ref.path
49+
}
50+
// unbind currently bound ref
51+
// bind ref
52+
// save unbind callback
53+
// probably save key or something as well
54+
})
1655
},
1756
modified: ({ oldIndex, newIndex, doc }) => {
1857
array.splice(oldIndex, 1)
1958
array.splice(newIndex, 0, createSnapshot(doc))
59+
// TODO replace listeners of nested refs
2060
},
2161
removed: ({ oldIndex }) => {
2262
array.splice(oldIndex, 1)
63+
// TODO remove listeners of nested refs
2364
}
2465
}
2566

test/helpers/mock.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ class CollectionReference {
111111
docChanges: [{
112112
type: 'added',
113113
doc: new DocumentSnapshot(null, id, data),
114-
newIndex: Object.keys(this.data).length,
114+
newIndex: Object.keys(this.data).length - 1,
115115
oldIndex: -1
116116
}]
117117
})

test/refs-collections.spec.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import Vuefire from '../src'
2+
import {
3+
db,
4+
tick,
5+
delay,
6+
Vue
7+
} from './helpers'
8+
9+
Vue.use(Vuefire)
10+
11+
let vm, collection, a, b, first, second
12+
beforeEach(async () => {
13+
a = db.collection().doc()
14+
b = db.collection().doc()
15+
await a.update({ isA: true })
16+
await b.update({ isB: true })
17+
collection = db.collection()
18+
first = await collection.add({ ref: a })
19+
second = await collection.add({ ref: b })
20+
21+
vm = new Vue({
22+
data: () => ({
23+
items: null
24+
})
25+
})
26+
await tick()
27+
})
28+
29+
test('binds refs on collections', async () => {
30+
await vm.$bind('items', collection)
31+
32+
// XXX dirty hack until $bind resolves when all refs are bound
33+
// NOTE should add option for it waitForRefs: true (by default)
34+
await delay(5)
35+
36+
expect(vm.items).toEqual([
37+
{ ref: { isA: true }},
38+
{ ref: { isB: true }}
39+
])
40+
})
41+
42+
test('binds refs when adding to collection', async () => {
43+
await vm.$bind('items', collection)
44+
const c = db.collection().doc()
45+
await c.update({ isC: true })
46+
47+
await collection.add({ ref: c })
48+
await delay(5)
49+
50+
expect(vm.items).toEqual([
51+
{ ref: { isA: true }},
52+
{ ref: { isB: true }},
53+
{ ref: { isC: true }}
54+
])
55+
})
File renamed without changes.

0 commit comments

Comments
 (0)