Skip to content

Commit

Permalink
feat(query): add ability to write custom query function for GeoFirest…
Browse files Browse the repository at this point in the history
…oreQuery

Need to test and then write docs for this
  • Loading branch information
MichaelSolati committed Aug 1, 2018
1 parent be8ab9a commit 05bccde
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 3 deletions.
1 change: 1 addition & 0 deletions src/interfaces/queryCriteria.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ import { firestore } from './firestore';
export interface QueryCriteria {
center?: firestore.GeoPoint;
radius?: number;
query?: (ref: firestore.CollectionReference) => firestore.Query;
}
8 changes: 7 additions & 1 deletion src/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export class GeoFirestoreQuery {
// Note that not all of these are currently within this query
private _locationsTracked: Map<string, LocationTracked> = new Map();
private _radius: number;
private _query: firestore.Query;

// Variables used to keep track of when to fire the 'ready' event
private _valueEventFired = false;
Expand Down Expand Up @@ -51,6 +52,7 @@ export class GeoFirestoreQuery {
validateCriteria(queryCriteria, true);
this._center = queryCriteria.center;
this._radius = queryCriteria.radius;
this._query = (queryCriteria.query) ? queryCriteria.query(this._collectionRef) : this._collectionRef;

// Listen for new geohashes being added around this query and fire the appropriate events
this._listenForNewGeohashes();
Expand Down Expand Up @@ -176,6 +178,10 @@ export class GeoFirestoreQuery {
validateCriteria(newQueryCriteria);
this._center = newQueryCriteria.center || this._center;
this._radius = newQueryCriteria.radius || this._radius;
this._query = (newQueryCriteria.query) ? newQueryCriteria.query(this._collectionRef) : this._query;
if (typeof newQueryCriteria.query === 'undefined') {
this._query = this._collectionRef;
}

// Loop through all of the locations in the query, update their distance from the center of the query, and fire any appropriate events
const keys: string[] = Array.from(this._locationsTracked.keys());
Expand Down Expand Up @@ -410,7 +416,7 @@ export class GeoFirestoreQuery {
const query: string[] = this._stringToQuery(toQueryStr);

// Create the Firebase query
const firestoreQuery: firestore.Query = this._collectionRef.orderBy('g').startAt(query[0]).endAt(query[1]);
const firestoreQuery: firestore.Query = this._query.orderBy('g').startAt(query[0]).endAt(query[1]);

// For every new matching geohash, determine if we should fire the 'key_entered' event
const childCallback = firestoreQuery.onSnapshot((snapshot: firestore.QuerySnapshot) => {
Expand Down
6 changes: 4 additions & 2 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,13 @@ export function validateGeoFirestoreObject(geoFirestoreObj: GeoFirestoreObj, fla
*/
export function validateCriteria(newQueryCriteria: QueryCriteria, requireCenterAndRadius = false): void {
if (typeof newQueryCriteria !== 'object') {
throw new Error('query criteria must be an object');
throw new Error('QueryCriteria must be an object');
} else if (typeof newQueryCriteria.center === 'undefined' && typeof newQueryCriteria.radius === 'undefined') {
throw new Error('radius and/or center must be specified');
} else if (requireCenterAndRadius && (typeof newQueryCriteria.center === 'undefined' || typeof newQueryCriteria.radius === 'undefined')) {
throw new Error('query criteria for a new query must contain both a center and a radius');
throw new Error('QueryCriteria for a new query must contain both a center and a radius');
} else if (Object.prototype.toString.call(newQueryCriteria.query) !== '[object Function]' && typeof newQueryCriteria.query !== 'undefined') {
throw new Error('query of QueryCriteria must be a function');
}

// Throw an error if there are any extraneous attributes
Expand Down

0 comments on commit 05bccde

Please sign in to comment.