-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathtutorial.js
151 lines (132 loc) · 3.97 KB
/
tutorial.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
'use strict';
// Setup for Node or Browserify. Skip if loading via browser script tags.
if(typeof window !== 'object') {
var PouchDB = require('pouchdb');
PouchDB.plugin(require('pouchdb-find'));
PouchDB.plugin(require('../lib/index'));
}
// Initial documents to seed
var smashers = [
{ name: 'Mario', _id: 'mario', series: 'Mario', debut: 1981 },
{ name: 'Jigglypuff', _id: 'puff', series: 'Pokemon', debut: 1996 },
{ name: 'Link', _id: 'link', series: 'Zelda', debut: 1986 },
{ name: 'Donkey Kong', _id: 'dk', series: 'Mario', debut: 1981 }
];
var db = new PouchDB('live-find', {db: require('memdown')});
var liveFeed;
// We need to create an index for pouchdb-find
db.createIndex({
index: {fields: ['series', 'name']}
})
// Seed initial documents
.then(function() {
return db.bulkDocs(smashers);
})
// Start our live query
.then(function() {
liveFeed = db.liveFind({
selector: {series: 'Mario'},
sort: [{series: 'desc'}, {name: 'desc'}],
aggregate: true
})
// Called every time there is an update to the query
.on('update', function(update, aggregate) {
// update.action is 'ADD', 'UPDATE', or 'REMOVE'
// update also contains id, rev, and doc
console.log(update.action, update.id);
// aggregate is an array of docs containing the latest state of the query
// the array is immutable which means that every change is a new Object
// this plays well with rendering engines like React and Angular
// change detection can be done by simply Object equality, `oldDoc === newDoc`
refreshUI(aggregate);
// (refreshUI would be a function you write to pipe the changes to your rendering engine)
})
// Called when the initial query is complete
.on('ready', function() {
console.log('Initial query complete.');
})
// Called when you invoke `liveFeed.cancel()`
.on('cancelled', function() {
console.log('LiveFind cancelled.');
})
// Called if there is any error
.on('error', function(err) {
console.error('Oh no!', err);
});
// liveFeed also contains a promise that will resolve when the initial query is complete
return liveFeed;
})
/* Outputs:
ADD dk
New List: [ 'Donkey Kong' ]
ADD mario
New List: [ 'Mario', 'Donkey Kong' ]
Initial query complete.
*/
// Add a doc
.then(function() {
var doc = { name: 'Wario', _id: 'wario', series: 'Mario', debut: 1992 };
return db.put(doc);
})
/* Outputs:
ADD wario
New List: [ 'Wario', 'Mario', 'Donkey Kong' ]
*/
// Update a doc
.then(function() {
return db.get('mario');
})
.then(function(mario) {
mario.name = 'Baby Mario';
return db.put(mario);
})
/* Outputs:
UPDATE mario
New List: [ 'Wario', 'Donkey Kong', 'Baby Mario' ]
*/
// When a doc no longer matches your query it is removed
.then(function() {
return db.get('dk');
}).then(function(dk) {
dk.series = 'Donkey Kong';
return db.put(dk);
})
/* Outputs:
REMOVE dk
New List: [ 'Wario', 'Baby Mario' ]
*/
// You can use the paginate function to change the sort order, skip and limit on the fly
.then(function() {
setTimeout(function() {
var newList = liveFeed.paginate({
sort: [{name: 'asc'}]
});
refreshUI(newList);
}, 10);
})
/* Outputs:
REMOVE dk
New List: [ 'Baby Mario', 'Wario' ]
*/
// When a change has no impact on your query nothing happens
.then(function() {
var doc = { name: 'Kirby', _id: 'kirby', series: 'Kirby', debut: 1992 };
return db.put(doc);
})
// (Outputs nothing)
// When you are done listening to updates cancel the listener to save resources
.then(function() {
// setTimeout prevents the feed from cancelling before it is finished processing updates
setTimeout(function() {
liveFeed.cancel();
}, 25);
});
// Outputs: "LiveFind cancelled."
// In a production app this would render the new list on the screen
// Right now we are just going to console.log the names in order
function refreshUI(list) {
var output = list.map(function(item) {
return item.name;
});
console.log('New List: ', output);
}