2

EDITED TO INCLUDE MORE DETAIL:

Let's assume I have a collection of Survey objects in Firebase, and a collection of SurveyTaker objects in Firebase, and a surveyTakersBySurvey relationship setup like

+-- surveyTakersBySurvey
   |
   +-- survey1
   |    |
   |    +-- surveyTaker1 = true
   |
   +-- survey2
        |
        +-- surveyTaker1 = true

This code currently works

findSurveyByState(surveyState:string): Observable<Survey> {
    return this.db.list('surveys', {
        query: {
            orderByChild: 'state',
            limitToFirst: 1,
            equalTo: surveyState
        }
    })
    .map(results => results[0]);
}

findSurveyTakerKeysPerSurveyState(surveyState:string,
                           query: FirebaseListFactoryOpts = {}): Observable<string[]> {
    return this.findSurveyByState(surveyState)
        .do(val => console.log("survey",val))
        .filter(survey => !!survey)
        .switchMap(survey => this.db.list(`surveyTakersBySurvey/${survey.$key}`,query))
        .map( stsbs => stsbs.map(stbs => stbs.$key) );
}

I need to change the above code to work for multiple surveys returned with the same state.

I'm struggling with rxjs programming...

//i first changed this to return multiple
findSurveysByState(surveyState:string): Observable<Survey[]> {
    return this.db.list('surveys', {
        query: {
            orderByChild: 'state',
            equalTo: surveyState
        }
    })
    //.map(results => results[0]);
}

// this is the method that is not working
findSurveyTakerKeysPerSurveyState(surveyState:string,
                           query: FirebaseListFactoryOpts = {}): Observable<string[]> {
    //need to update to take multiple Surveys
    return this.findSurveysByState(surveyState)
        .do(val => console.log("surveys",val))
        .filter(survey => !!survey)
        //.switchMap(survey => this.db.list(`surveyTakersBySurvey/${survey.$key}`,query))
        // switchMap would only make sense for one at a time?
        .map(surveys => surveys.map(survey => this.db.list(`surveyTakersBySurvey/${survey.$key}`, query)))
        // on the below line i get [ts] Property '$key' does not exist on type 'FirebaseListObservable<any[]>'.
        .map( stsbs => stsbs.map(stbs => stbs.$key) );
}

I get an [undefined, undefined]

Any help would be appreciated. Let me know if i need to elaborate on anything important.. i'm still feeling my way around here.

EDIT: this.db is from ... import { AngularFireDatabase } from "angularfire2/database";

8
  • when you console.log('stbss'), does it already contains the .$key in each of the element of the array? Commented Dec 18, 2017 at 5:41
  • It prints array of two FirebaseListObservables ... [FirebaseListObservable, FirebaseListObservable] ... i'm not sure how to print them out. Commented Dec 18, 2017 at 5:44
  • if you are using chrome console, you should be able to expand and see the objects inside Commented Dec 18, 2017 at 5:50
  • Yea it's a big crazy object like . 0 : FirebaseListObservable $ref : U {u: Qg, path: E, m: lf, Nc: false, then: undefined, …} operator : ObserveOnOperator {scheduler: ZoneScheduler, delay: 0} source : FirebaseListObservable {_isScalar: false, _subscribe: ƒ, $ref: U} _isScalar : false proto : Observable Commented Dec 18, 2017 at 5:54
  • it appears to be the same objects as a this.db.list('foo', query) . .. i'm just not sure how to map those to an array of strings Commented Dec 18, 2017 at 5:55

1 Answer 1

2

Use combineLatest.

findSurveyTakerKeysPerSurveyState(surveyState:string,
    query: FirebaseListFactoryOpts = {}): Observable<string[]> {
  //need to update to take multiple Surveys
  return this.findSurveysByState(surveyState)
  .do(val => console.log("surveys",val))
  .filter(survey => !!survey)
  //.switchMap(survey => this.db.list(`surveyTakersBySurvey/${survey.$key}`,query))
  // switchMap would only make sense for one at a time?
  .switchMap(surveys => {
    let observables = [];
    surveys.forEach(survey => {
      observables.push(this.db.list(`surveyTakersBySurvey/${survey.$key}`, query));
    });
    return Observable.combineLatest(observables);
  })
  .map( stsbs => stsbs.map(stbs => stbs.$key) );
}

You may need to import these two lines.

import 'rxjs/add/observable/combineLatest';
import { Observable } from 'rxjs/Observable';
Sign up to request clarification or add additional context in comments.

2 Comments

Well, you are just amazing. Thank you. I also needed to add .map( stsbs => stsbs.map(results => results[0]).map(stbs => stbs.$key) );
Glad to hear that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.