Skip to content

Commit d5351b5

Browse files
authored
Merge pull request #912 from somombo/@somombo/add-list-set
feat(FirebaseListObservable): add `set` method for destructive updates
2 parents cc1a662 + 34fa431 commit d5351b5

File tree

3 files changed

+118
-2
lines changed

3 files changed

+118
-2
lines changed

docs/3-retrieving-data-as-lists.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,19 @@ const items = db.list('/items');
120120
items.push({ name: newName });
121121
```
122122

123-
### Updating items in the list
123+
### Replacing items in the list using `set`
124+
125+
Use the `set()` method to update existing items.
126+
127+
```ts
128+
const items = af.database.list('/items');
129+
// to get a key, check the Example app below
130+
items.set('key-of-some-data', { size: newSize });
131+
```
132+
133+
Replaces the current value in the database with the new value specified as the parameter. This is called a destructive update, because it deletes everything currently in place and saves the new value.
134+
135+
### Updating items in the list using `update`
124136

125137
Use the `update()` method to update existing items.
126138

@@ -130,6 +142,8 @@ const items = db.list('/items');
130142
items.update('key-of-some-data', { size: newSize });
131143
```
132144

145+
Note that this updates the current value with in the database with the new value specified as the parameter. This is called a non-destructive update, because it only updates the values specified.
146+
133147
### Removing items from the list
134148
Use the `remove()` method to remove data at the list item's location.
135149

src/database/firebase_list_observable.spec.ts

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,99 @@ describe('FirebaseListObservable', () => {
145145
})
146146
});
147147

148+
149+
describe('set', () => {
150+
let orphan = { orphan: true };
151+
let child:firebase.database.Reference;
152+
153+
beforeEach(() => {
154+
child = ref.push(orphan);
155+
});
156+
157+
it('should set(replace) the item from the Firebase db when given the key', (done:any) => {
158+
let childChangedSpy = jasmine.createSpy('childChanged');
159+
const orphanChange = { changed: true }
160+
ref.on('child_changed', childChangedSpy);
161+
O.set(child.key, orphanChange)
162+
.then(() => (<any>ref).once('value'))
163+
.then((data:firebase.database.DataSnapshot) => {
164+
expect(childChangedSpy.calls.argsFor(0)[0].val()).not.toEqual({
165+
orphan: true,
166+
changed: true
167+
});
168+
expect(childChangedSpy.calls.argsFor(0)[0].val()).toEqual({
169+
changed: true
170+
});
171+
172+
ref.off();
173+
})
174+
.then(done, done.fail);
175+
});
176+
177+
it('should set(replace) the item from the Firebase db when given the reference', (done:any) => {
178+
let childChangedSpy = jasmine.createSpy('childChanged');
179+
const orphanChange = { changed: true }
180+
ref.on('child_changed', childChangedSpy);
181+
O.set(child.ref, orphanChange)
182+
.then(() => (<any>ref).once('value'))
183+
.then((data:firebase.database.DataSnapshot) => {
184+
expect(childChangedSpy.calls.argsFor(0)[0].val()).not.toEqual({
185+
orphan: true,
186+
changed: true
187+
});
188+
expect(childChangedSpy.calls.argsFor(0)[0].val()).toEqual({
189+
changed: true
190+
});
191+
192+
ref.off();
193+
})
194+
.then(done, done.fail);
195+
});
196+
197+
it('should set(replace) the item from the Firebase db when given the snapshot', (done:any) => {
198+
let childChangedSpy = jasmine.createSpy('childChanged');
199+
const orphanChange = { changed: true }
200+
ref.on('child_changed', childChangedSpy);
201+
O.set(child, orphanChange)
202+
.then(() => (<any>ref).once('value'))
203+
.then((data:firebase.database.DataSnapshot) => {
204+
expect(childChangedSpy.calls.argsFor(0)[0].val()).not.toEqual({
205+
orphan: true,
206+
changed: true
207+
});
208+
expect(childChangedSpy.calls.argsFor(0)[0].val()).toEqual({
209+
changed: true
210+
});
211+
212+
ref.off();
213+
})
214+
.then(done, done.fail);
215+
});
216+
217+
it('should set(replace) the item from the Firebase db when given the unwrapped snapshot', (done:any) => {
218+
const orphanChange = { changed: true }
219+
ref.on('child_added', (data:firebase.database.DataSnapshot) => {
220+
expect(data.val()).toEqual(orphan);
221+
O.set(unwrapMapFn(data), orphanChange)
222+
.then(() => (<any>child).once('value'))
223+
.then((data:firebase.database.DataSnapshot) => {
224+
expect(data.val()).not.toEqual({
225+
orphan: true,
226+
changed: true
227+
});
228+
expect(data.val()).toEqual({
229+
changed: true
230+
});
231+
ref.off();
232+
})
233+
.then(done, done.fail);
234+
});
235+
});
236+
237+
});
238+
239+
240+
148241
describe('update', () => {
149242
let orphan = { orphan: true };
150243
let child:firebase.database.Reference;

src/database/firebase_list_observable.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,15 @@ export class FirebaseListObservable<T> extends Observable<T> {
2828
return this.$ref.ref.push(val);
2929
}
3030

31+
set(item: FirebaseOperation, value: Object): firebase.Promise<void> {
32+
return this._checkOperationCases(item, {
33+
stringCase: () => this.$ref.ref.child(<string>item).set(value),
34+
firebaseCase: () => (<firebase.database.Reference>item).set(value),
35+
snapshotCase: () => (<firebase.database.DataSnapshot>item).ref.set(value),
36+
unwrappedSnapshotCase: () => this.$ref.ref.child((<AFUnwrappedDataSnapshot>item).$key).set(value)
37+
});
38+
}
39+
3140
update(item: FirebaseOperation, value: Object): firebase.Promise<void> {
3241
return this._checkOperationCases(item, {
3342
stringCase: () => this.$ref.ref.child(<string>item).update(value),
@@ -50,7 +59,7 @@ export class FirebaseListObservable<T> extends Observable<T> {
5059
});
5160
}
5261

53-
_checkOperationCases(item: FirebaseOperation, cases: FirebaseOperationCases) : firebase.Promise<void> {
62+
protected _checkOperationCases(item: FirebaseOperation, cases: FirebaseOperationCases) : firebase.Promise<void> {
5463
if (utils.isString(item)) {
5564
return cases.stringCase();
5665
} else if (utils.isFirebaseRef(item)) {

0 commit comments

Comments
 (0)