diff --git a/docs/api-reference.md b/docs/api-reference.md index 7025c7992..0cdd86929 100644 --- a/docs/api-reference.md +++ b/docs/api-reference.md @@ -225,13 +225,72 @@ class App { } ``` + ### FirebaseListObservable Subclass of rxjs `Observable` which also has methods for updating list-like Firebase data. -type: `class` +Type: `class` + +Properties: + +`$ref:(firebase.database.Reference)`: The reference used to sync this +collection to the Firebase database. See +[firebase.database.Reference](https://firebase.google.com/docs/reference/js/firebase.database.Reference) + +Methods: + +`push:(val) => Promise`: Add an element to the Firebase Database. +This is the equivalent of the Firebase SDK's +[set() method](https://firebase.google.com/docs/reference/js/firebase.database.Reference#set). +See [Saving Data](https://firebase.google.com/docs/database/web/save-data) +for info about restricted characters in object keys and more details about +saving data in the Database. + +`update:(item:Object) => void`: Replace any child keys provided in `val` +with the values provided, but do not touch any other keys in the element. +This is the equivalent of the Firebase SDK's +[update() method](https://firebase.google.com/docs/reference/js/firebase.database.Reference#update). + +`remove:([item]) => void`: Remove an element from the Firebase Database. +If no `item` argument is provided, it removes all elements from the list. + This is the equivalent of the Firebase SDK's + [remove() method](https://firebase.google.com/docs/reference/js/firebase.database.Reference#remove). + +### FirebaseObjectObservable + +Subclass of rxjs `Observable` which also has methods for syncing and +updating object-like Firebase data. {For collections and lists, see +FirebaseListObservable.) + +Type: `class` + +Properties: + +`$ref:(firebase.database.Reference)`: The reference used to sync +this collection to the Firebase database. See +[firebase.database.Reference](https://firebase.google.com/docs/reference/js/firebase.database.Reference) + +Methods: + +`set:(val:any) => Promise`: Replaces any data at this path in the Database + with the value provided here (or adds the data if it doesn't exist). + This is the equivalent of the Firebase SDK's +[set() method](https://firebase.google.com/docs/reference/js/firebase.database.Reference#set). +See [Saving Data](https://firebase.google.com/docs/database/web/save-data) +for info about restricted characters in object keys and more details about +saving data in the Database. -additional methods: +`update:(val:Object) => void`: Replace any child keys provided in `val` +with the values provided here. The primary difference between this method +and `set()` above, is that `update()` modifies only the keys provided, +leaving any other data untouched, where `set()` essentially replaces +all data at the given path. +This is the equivalent of the Firebase SDK's +[update() method](https://firebase.google.com/docs/reference/js/firebase.database.Reference#update). -`add:(val) => void`: Add an element to the Firebase ref. +`remove:() => void`: Remove an element from the Firebase Database. +If no `item` argument is provided, it removes all elements from the list. + This is the equivalent of the Firebase SDK's + [remove() method](https://firebase.google.com/docs/reference/js/firebase.database.Reference#remove). diff --git a/src/database/firebase_list_factory.spec.ts b/src/database/firebase_list_factory.spec.ts index a53d71ea8..94beeda19 100644 --- a/src/database/firebase_list_factory.spec.ts +++ b/src/database/firebase_list_factory.spec.ts @@ -364,8 +364,8 @@ describe('FirebaseListFactory', () => { firebase.database().ref().remove(done); questions = FirebaseListFactory(`${rootDatabaseUrl}/questions`); questionsSnapshotted = FirebaseListFactory(`${rootDatabaseUrl}/questionssnapshot`, { preserveSnapshot: true }); - ref = (questions)._ref; - refSnapshotted = (questionsSnapshotted)._ref; + ref = (questions).$ref; + refSnapshotted = (questionsSnapshotted).$ref; }); afterEach((done: any) => { @@ -377,7 +377,7 @@ describe('FirebaseListFactory', () => { it('should emit only when the initial data set has been loaded', (done: any) => { - (questions)._ref.set([{ initial1: true }, { initial2: true }, { initial3: true }, { initial4: true }]) + (questions).$ref.set([{ initial1: true }, { initial2: true }, { initial3: true }, { initial4: true }]) .then(() => toPromise.call(skipAndTake(questions, 1))) .then((val: any[]) => { expect(val.length).toBe(4); diff --git a/src/database/firebase_list_observable.spec.ts b/src/database/firebase_list_observable.spec.ts index d991d4b36..7c0e8b384 100644 --- a/src/database/firebase_list_observable.spec.ts +++ b/src/database/firebase_list_observable.spec.ts @@ -1,6 +1,5 @@ import { FirebaseListObservable } from './index'; import { Observer } from 'rxjs/Observer'; -import { Observable } from 'rxjs/Observable'; import { map } from 'rxjs/operator/map'; import { database } from 'firebase'; import { unwrapMapFn } from '../utils'; @@ -49,6 +48,16 @@ describe('FirebaseObservable', () => { expect(map.call(O, noop) instanceof FirebaseListObservable).toBe(true); }); + describe('$ref', () => { + // it('should be a firebase.database.Reference', () => { + // expect(O.$ref instanceof database.Reference).toBe(true); + // }); + + it('should match the database path passed in the constructor', () => { + expect(O.$ref.toString()).toEqual(ref.toString()); + }); + }); + describe('push', () => { it('should throw an exception if pushed when not subscribed', () => { O = new FirebaseListObservable(null, (observer:Observer) => {}); diff --git a/src/database/firebase_list_observable.ts b/src/database/firebase_list_observable.ts index 02f135500..19ed4c433 100644 --- a/src/database/firebase_list_observable.ts +++ b/src/database/firebase_list_observable.ts @@ -2,40 +2,40 @@ import { Observable } from 'rxjs/Observable'; import { Operator } from 'rxjs/Operator'; import { Subscriber } from 'rxjs/Subscriber'; import { Subscription } from 'rxjs/Subscription'; +import * as firebase from 'firebase'; import * as utils from '../utils'; -import { - AFUnwrappedDataSnapshot, - FirebaseOperationCases +import { + AFUnwrappedDataSnapshot, + FirebaseOperationCases } from '../interfaces'; export type FirebaseOperation = string | firebase.database.Reference | firebase.database.DataSnapshot | AFUnwrappedDataSnapshot; export class FirebaseListObservable extends Observable { - constructor(public _ref: firebase.database.Reference | firebase.database.Query, subscribe?: (subscriber: Subscriber) => Subscription | Function | void) { + constructor(public $ref: firebase.database.Reference | firebase.database.Query, subscribe?: (subscriber: Subscriber) => Subscription | Function | void) { super(subscribe); } lift(operator: Operator): Observable { - const observable = new FirebaseListObservable(this._ref); + const observable = new FirebaseListObservable(this.$ref); observable.source = this; observable.operator = operator; - observable._ref = this._ref; + observable.$ref = this.$ref; return observable; } push(val:any):firebase.database.ThenableReference { - if(!this._ref) { + if(!this.$ref) { throw new Error('No ref specified for this Observable!'); } - this._ref.ref - return this._ref.ref.push(val); + return this.$ref.ref.push(val); } update(item: FirebaseOperation, value: Object): firebase.Promise { return this._checkOperationCases(item, { - stringCase: () => this._ref.ref.child(item).update(value), + stringCase: () => this.$ref.ref.child(item).update(value), firebaseCase: () => (item).update(value), snapshotCase: () => (item).ref.update(value), - unwrappedSnapshotCase: () => this._ref.ref.child((item).$key).update(value) + unwrappedSnapshotCase: () => this.$ref.ref.child((item).$key).update(value) }); } @@ -45,13 +45,13 @@ export class FirebaseListObservable extends Observable { // if no item parameter is provided, remove the whole list if (!item) { - return this._ref.ref.remove(); + return this.$ref.ref.remove(); } return this._checkOperationCases(item, { - stringCase: () => this._ref.ref.child(item).remove(), + stringCase: () => this.$ref.ref.child(item).remove(), firebaseCase: () => (item).remove(), snapshotCase: () => (item).ref.remove(), - unwrappedSnapshotCase: () => this._ref.ref.child((item).$key).remove() + unwrappedSnapshotCase: () => this.$ref.ref.child((item).$key).remove() }); } diff --git a/src/database/firebase_object_factory.spec.ts b/src/database/firebase_object_factory.spec.ts index 59521dc24..d26e8e0cb 100644 --- a/src/database/firebase_object_factory.spec.ts +++ b/src/database/firebase_object_factory.spec.ts @@ -70,7 +70,7 @@ describe('FirebaseObjectFactory', () => { it('should emit a null value if no value is present when subscribed', (done: any) => { subscription = observable.subscribe(unwrapped => { - const expectedObject = { $key: (observable)._ref.key, $value: null }; + const expectedObject = { $key: (observable).$ref.key, $value: null }; expect(unwrapped.$key).toEqual(expectedObject.$key); expect(unwrapped.$value).toEqual(expectedObject.$value); expect(unwrapped.$exists()).toEqual(false); diff --git a/src/database/firebase_object_observable.spec.ts b/src/database/firebase_object_observable.spec.ts index 5c4945b5a..fa19bc60b 100644 --- a/src/database/firebase_object_observable.spec.ts +++ b/src/database/firebase_object_observable.spec.ts @@ -47,6 +47,16 @@ describe('FirebaseObjectObservable', () => { expect(map.call(O, noop) instanceof FirebaseObjectObservable).toBe(true); }); + describe('$ref', () => { + // it('should be a firebase.database.Reference', () => { + // expect(O.$ref instanceof database.Reference).toBe(true); + // }); + + it('should match the database path passed in the constructor', () => { + expect(O.$ref.toString()).toEqual(ref.toString()); + }); + }); + describe('set', () => { it('should call set on the underlying ref', (done:any) => { diff --git a/src/database/firebase_object_observable.ts b/src/database/firebase_object_observable.ts index 776c9c3f8..66dc8bcef 100644 --- a/src/database/firebase_object_observable.ts +++ b/src/database/firebase_object_observable.ts @@ -2,34 +2,35 @@ import { Observable } from 'rxjs/Observable'; import { Operator } from 'rxjs/Operator'; import { Subscriber } from 'rxjs/Subscriber'; import { Subscription } from 'rxjs/Subscription'; +import * as firebase from 'firebase'; export class FirebaseObjectObservable extends Observable { - constructor(subscribe?: (subscriber: Subscriber) => Subscription | Function | void, private _ref?:firebase.database.Reference) { + constructor(subscribe?: (subscriber: Subscriber) => Subscription | Function | void, public $ref?:firebase.database.Reference) { super(subscribe); } lift(operator: Operator): Observable { const observable = new FirebaseObjectObservable(); observable.source = this; observable.operator = operator; - observable._ref = this._ref; + observable.$ref = this.$ref; return observable; } set(value: any): firebase.Promise { - if(!this._ref) { + if(!this.$ref) { throw new Error('No ref specified for this Observable!'); } - return this._ref.set(value); + return this.$ref.set(value); } update(value: Object): firebase.Promise { - if(!this._ref) { + if(!this.$ref) { throw new Error('No ref specified for this Observable!'); } - return this._ref.update(value); + return this.$ref.update(value); } remove(): firebase.Promise { - if(!this._ref) { + if(!this.$ref) { throw new Error('No ref specified for this Observable!'); } - return this._ref.remove(); + return this.$ref.remove(); } }