Skip to content
This repository was archived by the owner on Apr 4, 2023. It is now read-only.

Commit 0475099

Browse files
committed
[query] - Accept errorCallback for query.on()
1 parent 8c5fb79 commit 0475099

File tree

4 files changed

+44
-60
lines changed

4 files changed

+44
-60
lines changed

src/app/database/index.ts

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,7 @@ import * as firebase from "../../firebase";
22
import { nextPushId } from "./util/NextPushId";
33

44
export namespace database {
5-
export interface DataSnapshot {
6-
// child(path: string): DataSnapshot;
7-
exists(): boolean;
8-
// exportVal(): any;
9-
// forEach(action: (a: DataSnapshot) => boolean): boolean;
10-
// getPriority(): string | number | null;
11-
// hasChild(path: string): boolean;
12-
// hasChildren(): boolean;
13-
key: string | null;
14-
// numChildren(): number;
15-
// ref: Reference;
16-
// toJSON(): Object | null;
17-
val(): any;
18-
}
5+
export type DataSnapshot = firebase.DataSnapshot;
196

207
export class Query implements firebase.Query {
218
protected path: string;
@@ -29,12 +16,13 @@ export namespace database {
2916
* Listens for data changes at a particular location
3017
* @param eventType One of the following strings: "value", "child_added", "child_changed", "child_removed", or "child_moved."
3118
* @param callback A callback that fires when the specified event occurs. The callback will be passed a DataSnapshot.
19+
* @param cancelCallbackOrContext A callback that fires when an error occurs. The callback will be passed an error object.
3220
* @returns The provided callback function is returned unmodified.
3321
*/
3422
public on(eventType: string, callback: (a: DataSnapshot | null, b?: string) => any,
35-
cancelCallbackOrContext?: Object | null, context?: Object | null): (a: DataSnapshot | null, b?: string) => Function {
23+
cancelCallbackOrContext?: (a: Error | null) => any, context?: Object | null): (a: DataSnapshot | null, b?: string) => Function {
3624

37-
this.queryObject.on(eventType, callback);
25+
this.queryObject.on(eventType, callback, cancelCallbackOrContext);
3826

3927
return callback; // According to firebase doc we just return the callback given
4028
}

src/firebase.android.ts

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1640,25 +1640,19 @@ class Query implements QueryBase {
16401640
this.query = this.dbRef;
16411641
}
16421642

1643-
on(eventType: string, callback: (a: any, b?: string) => any): Function {
1644-
const onValueEvent = result => {
1645-
callback(result);
1646-
};
1647-
1643+
on(eventType: string, callback: (a: DataSnapshot, b?: string) => any, cancelCallbackOrContext?: (a: Error | null) => any): Function {
16481644
try {
16491645
if (firebase.instance === null) {
16501646
throw new Error("Run init() first!");
16511647
}
1652-
const listener = this.createEventListener(eventType, onValueEvent);
1648+
const listener = this.createEventListener(eventType, callback, cancelCallbackOrContext);
16531649

16541650
if (eventType === "value") {
16551651
this.query.addValueEventListener(listener as com.google.firebase.database.ValueEventListener);
16561652
} else if (eventType === "child_added" || eventType === "child_changed" || eventType === "child_removed" || eventType === "child_moved") {
16571653
this.query.addChildEventListener(listener as com.google.firebase.database.ChildEventListener);
16581654
} else {
1659-
callback({
1660-
error: "Invalid eventType. Use one of the following: 'value', 'child_added', 'child_changed', 'child_removed', or 'child_moved'"
1661-
});
1655+
throw new Error(`${eventType} is not a valid eventType. Use one of the following: 'value', 'child_added', 'child_changed', 'child_removed', or 'child_moved'`);
16621656
}
16631657
// Add listener to our map which keeps track of eventType: child/value events
16641658
if (!Query.eventListenerMap.has(eventType)) {
@@ -1667,6 +1661,9 @@ class Query implements QueryBase {
16671661
Query.eventListenerMap.get(eventType).push(listener); // We need to keep track of the listeners to fully remove them when calling off
16681662
} catch (ex) {
16691663
console.error("Error in firebase.on: " + ex);
1664+
if (cancelCallbackOrContext !== undefined) {
1665+
cancelCallbackOrContext(ex);
1666+
}
16701667
} finally {
16711668
return callback;
16721669
}
@@ -1693,7 +1690,7 @@ class Query implements QueryBase {
16931690
firebase.instance.child(this.path).addListenerForSingleValueEvent(listener);
16941691
}
16951692
catch (ex) {
1696-
console.log("Error in firebase.once: " + ex);
1693+
console.error("Error in firebase.once: " + ex);
16971694
reject(ex);
16981695
}
16991696
});
@@ -1776,7 +1773,7 @@ class Query implements QueryBase {
17761773
* to specific events (Android is more generic value / child - which includes all events add, change, remove etc).
17771774
* Similar to firebase._addObserver but I do not want to listen for every event
17781775
*/
1779-
private createEventListener(eventType: string, callback): com.google.firebase.database.ValueEventListener | com.google.firebase.database.ChildEventListener {
1776+
private createEventListener(eventType: string, callback, cancelCallback?): com.google.firebase.database.ValueEventListener | com.google.firebase.database.ChildEventListener {
17801777
let listener;
17811778

17821779
if (eventType === "value") {
@@ -1785,17 +1782,17 @@ class Query implements QueryBase {
17851782
callback(nativeSnapshotToWebSnapshot(snapshot));
17861783
},
17871784
onCancelled: (databaseError: com.google.firebase.database.DatabaseError) => {
1788-
callback({
1789-
error: databaseError.getMessage()
1790-
});
1785+
if (cancelCallback !== undefined) {
1786+
cancelCallback(new Error(databaseError.getMessage()));
1787+
}
17911788
}
17921789
});
17931790
} else if (eventType === "child_added" || eventType === "child_changed" || eventType === "child_removed" || eventType === "child_moved") {
17941791
listener = new com.google.firebase.database.ChildEventListener({
17951792
onCancelled: (databaseError: com.google.firebase.database.DatabaseError) => {
1796-
callback({
1797-
error: databaseError.getMessage()
1798-
});
1793+
if (cancelCallback !== undefined) {
1794+
cancelCallback(new Error(databaseError.getMessage()));
1795+
}
17991796
},
18001797
onChildAdded: (snapshot: com.google.firebase.database.DataSnapshot, previousChildKey: string) => {
18011798
if (eventType === "child_added") {

src/firebase.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,7 @@ export interface OnDisconnect {
549549

550550
// WebAPI Query
551551
export interface Query {
552-
on(eventType: string, callback: (a: any, b?: string) => any): Function;
552+
on(eventType: string, callback: (a: any, b?: string) => any, cancelCallbackOrContext?: (a: Error | null) => any): Function;
553553

554554
once(eventType: string): Promise<DataSnapshot>;
555555

src/firebase.ios.ts

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1402,30 +1402,29 @@ class Query implements QueryBase {
14021402
this.query = this.dbRef;
14031403
}
14041404

1405-
on(eventType: string, callback: (a: any, b?: string) => any): Function {
1406-
const onValueEvent = result => {
1407-
callback(result);
1408-
};
1409-
try {
1410-
if (eventType === "value" || eventType === "child_added" || eventType === "child_changed"
1411-
|| eventType === "child_removed" || eventType === "child_moved") {
1412-
const firDataEventType = this.eventToFIRDataEventType(eventType);
1413-
const firDatabaseHandle = this.attachEventObserver(this.query, firDataEventType, onValueEvent);
1414-
if (!Query.eventListenerMap.has(eventType)) {
1415-
Query.eventListenerMap.set(eventType, []);
1416-
}
1417-
Query.eventListenerMap.get(eventType).push(firDatabaseHandle); // We need to keep track of the listeners to fully remove them when calling off
1418-
} else {
1419-
callback({
1420-
error: "Invalid eventType. Use one of the following: 'value', 'child_added', 'child_changed', 'child_removed', or 'child_moved'"
1421-
});
1405+
on(eventType: string, callback: (a: any, b?: string) => any, cancelCallbackOrContext?: (a: Error | null) => any): Function {
1406+
try {
1407+
if (eventType === "value" || eventType === "child_added" || eventType === "child_changed"
1408+
|| eventType === "child_removed" || eventType === "child_moved") {
1409+
const firDataEventType = this.eventToFIRDataEventType(eventType);
1410+
const firDatabaseHandle = this.attachEventObserver(this.query, firDataEventType, callback, cancelCallbackOrContext);
1411+
if (!Query.eventListenerMap.has(eventType)) {
1412+
Query.eventListenerMap.set(eventType, []);
14221413
}
1423-
} catch (ex) {
1424-
console.log("Error in firebase.on: " + ex);
1414+
Query.eventListenerMap.get(eventType).push(firDatabaseHandle); // We need to keep track of the listeners to fully remove them when calling off
1415+
} else {
1416+
throw new Error(`${eventType} is not a valid eventType. Use one of the following: 'value', 'child_added', 'child_changed', 'child_removed', or 'child_moved'`);
14251417
}
1426-
finally {
1427-
return callback;
1418+
} catch (ex) {
1419+
// TODO: Make custom errors
1420+
console.error("Error in firebase.on: " + ex);
1421+
if (cancelCallbackOrContext !== undefined) {
1422+
cancelCallbackOrContext(ex);
14281423
}
1424+
}
1425+
finally {
1426+
return callback;
1427+
}
14291428
}
14301429

14311430
once(eventType: string): Promise<DataSnapshot> {
@@ -1443,7 +1442,7 @@ class Query implements QueryBase {
14431442
});
14441443
});
14451444
} catch (ex) {
1446-
console.log("Error in firebase.once: " + ex);
1445+
console.error("Error in firebase.once: " + ex);
14471446
reject(ex);
14481447
}
14491448
});
@@ -1548,16 +1547,16 @@ class Query implements QueryBase {
15481547
* to specific events (Android is more generic value / child - which includes all events add, change, remove etc).
15491548
* Similar to firebase._addObserver but I do not want to listen for every event
15501549
*/
1551-
private attachEventObserver(dbRef: FIRDatabaseQuery | FIRDatabaseReference, firEventType: FIRDataEventType, callback): number {
1550+
private attachEventObserver(dbRef: FIRDatabaseQuery | FIRDatabaseReference, firEventType: FIRDataEventType, callback, cancelCallback): number {
15521551
const listener = dbRef.observeEventTypeWithBlockWithCancelBlock(
15531552
firEventType,
15541553
snapshot => {
15551554
callback(nativeSnapshotToWebSnapshot(snapshot));
15561555
},
15571556
firebaseError => {
1558-
callback({
1559-
error: firebaseError.localizedDescription
1560-
});
1557+
if (cancelCallback !== undefined) {
1558+
cancelCallback(new Error(firebaseError.localizedDescription));
1559+
}
15611560
});
15621561
return listener;
15631562
}

0 commit comments

Comments
 (0)