6

Tech: I'm using Angular 7, Firestore, GeoFireX.

Outcome I want: I want to add .where queries if that query is required by the users. For example below I have four .wheres. I might only need two sometimes and therefore will only want to add two using maybe an if statement if user search by sector and brand (see method: basicQueryBuilder)

The code below works, but is not dynamic.

Additionally, can a this.geo.collection from GeoFireX have a .limit(20) just like a normal collection can?

Current Attempt:

  public getFirestoreJobs(queryType: string, limit: number, pageSize: number): Observable<any> {
    limit = limit + pageSize;

    if (queryType === 'geo') {
      const collection = this.geoQueryBuilder();
      const center = this.geo.point(51.5074, 0.1278);
      const radius = 20;

      return collection.within(center, radius, 'point');
    } else {
      const collection = this.basicQueryBuilder();

      return collection.valueChanges();
    }
  }

  public geoQueryBuilder(): any  {
    return this.geo.collection('jobs', ref => ref
      .where('sector', '==', 'teacher')
      .where('brand', '==', 'all')
      .where('payType', '==', 'salary')
      .where('tags', 'array-contains', 'salary'));
  }

  public basicQueryBuilder(): any {
    return this.angularFirestore.collection('jobs', ref => ref
      .where('sector', '==', 'teacher')
      .where('brand', '==', 'all')
      .where('payType', '==', 'salary')
      .where('tags', 'array-contains', 'salary').limit(20));
  }

Second attempt:

  let query = this.angularFirestore.collection('jobs');
  query = query.where('sector', '==', 'teacher');
  query = query.where('brand', '==', 'all');

  return query.valueChanges();

Error I get:

error TS2322: Type 'Query' is not assignable to type 'CollectionReference'.

AngularM
  • 15,982
  • 28
  • 94
  • 169
  • 1
    Firestore queries use the builder pattern, so you can deal with each stage of the build conditionally by reassigning to some object that represents the current stage of the build. – Doug Stevenson Feb 12 '19 at 22:22
  • @DougStevenson the question you labelled this as a duplicate with doesnt work using the query - query.where – AngularM Feb 12 '19 at 22:33
  • It should. You'll need to be more specific about what exactly does not work. – Doug Stevenson Feb 12 '19 at 22:35
  • @DougStevenson I've added a second attempt above. But I get an error. See above change please. Thanks – AngularM Feb 12 '19 at 22:40
  • It looks like you need to conditionally apply the filters inside the callback function that accepts `ref`, not after it. I don't know enough about the angular wrapper for Firestore to try this myself, so I'll remove the dup. – Doug Stevenson Feb 12 '19 at 22:45
  • Thank you. I've removed angularfire for this and I just do a normal firestore call. I get this error: error TS2322: Type 'Query' is not assignable to type 'CollectionReference'. – AngularM Feb 12 '19 at 22:46
  • 1
    So slightly biased, but you could use `geofirestore` which behaves more like regular Firestore (so you can assign your query/collection and dynamically chain and reassign your query). It also supports the `limit` method, however there are some performance considerations. Also it doesn't return Observables, like the plain Firestore library, but you can use RxJS and create your own Observables. – MichaelSolati Feb 13 '19 at 04:34
  • Thanks Michael, whats the database fields per document? The document says: g: string; l: GeoPoint; d: DocumentData; But those dont return anything – AngularM Feb 13 '19 at 10:28
  • MichaelSolati, do you have pagination for your geofire? I need to use startAfter / StartAt e.g. so I can get 20 new results at a time. Is this possible? – AngularM Feb 13 '19 at 14:57

1 Answers1

7
import {Query, QueryFn } from '@angular/fire/firestore';

    this.angularFirestore.collection('jobs', ref => {
    let query : Query = ref;
    if(condition1) {
     query = query.where('sector', '==', 'teacher');
    }
    if(condition2) {
     query = query.where('brand', '==', 'all');
    }
    return query;
    })
Sai Sundeep
  • 273
  • 2
  • 7