Transform an array of FirebaseListObservables into an array of strings

UPDATED FOR MORE DETAIL:

Imagine I have a collection of Survey objects and SurveyTaker objects in Firebase, with a relationship set up as follows:

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

The code provided is currently functioning as expected.

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 now need to modify the above code to handle multiple surveys returned with the same state.

I am facing challenges with rxjs programming...

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

// Method that needs updating
findSurveyTakerKeysPerSurveyState(surveyState:string,
                           query: FirebaseListFactoryOpts = {}): Observable<string[]> {
    // Update to handle 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)))
        // Error on line below: Property '$key' does not exist on type 'FirebaseListObservable<any[]>'.
        .map( stsbs => stsbs.map(stbs => stbs.$key) );
}

I am receiving an [undefined, undefined] output.

Any assistance would be greatly appreciated. Please let me know if further clarification is required. Thank you!

NOTE: this.db is imported from { AngularFireDatabase } from "angularfire2/database";

Answer №1

Utilize the combineLatest method.

findSurveyTakerKeysPerSurveyState(surveyState:string,
    query: FirebaseListFactoryOpts = {}): Observable<string[]> {
  //update required to handle 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) );
}

Make sure to import these two lines as well.

import 'rxjs/add/observable/combineLatest';
import { Observable } from 'rxjs/Observable';

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What sets apart `this.user.id` from `this.user = {id: ....}`?

I am puzzled by the error thrown in the code below: import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; @Component({ selector: 'app-user', templateUrl: './user.compone ...

Adjust the size of a map on an HTML page after it has

Currently, I am utilizing Angular 2 to create a simple webpage that includes a Google 'my map' displayed within a modal. <iframe id="map" class="center" src="https://www.google.com/maps/d/u/0/embed?mid=1uReFxtB4ZhFSwVtD8vQ7L3qKpetdMElh&ll ...

Access a designated webpage with precision by utilizing Routes in Angular

Is it possible to display a different component in Angular routing based on a condition in the Routing file? For example, if mineType is equal to "mino", can I navigate to another component instead of the one declared in the Routing? Should I use Child ro ...

Angular template error: Potential is present but not defined

Encountering an issue with my Angular application's template file (dashboard.component.html). The error message reads "Object is possibly 'undefined'." Here's the portion of the template that seems to be causing the problem: <div> ...

Unable to retrieve data list in Angular TypeScript

After sending a request to the server and receiving a list of data, I encountered an issue where the data appears to be empty when trying to use it in another function within the same file. The code snippet below initializes an array named tree: tree:any ...

What is the best way to create a for loop that collects all the weekdays falling between two specific months?

My current task involves gathering all the days of the week from Sunday to Saturday, starting with the actual date. I started working on a code that uses a for loop to push each day into an array. However, I encountered a problem with weeks that span acros ...

Techniques for concealing a button when the "disabled" attribute is set to "true"

The button is currently disabled, however, I intended for it to be hidden from the UI when the disabled condition is met - <button ion-button block class="button-color-blue" [disabled]="true" (click)="closePage()"> Cancel </b ...

The modifications to the URL made by react-router-dom's 'useSearchParams' do not persist when adjusted through the onChange callback of the mui 'Tabs' component

One feature I am looking to implement is a tab navigation component that changes based on a specific search parameter called tab. For instance, if my URL reads as example.com?tab=test2, I want the navigation bar to highlight the item labeled test2. To ac ...

In Vue using Typescript, how would I go about defining a local data property that utilizes a prop as its initial value?

When passing a prop to a child component in Vue, the documentation states: The parent component updates will refresh all props in the child component with the latest value. Avoid mutating a prop inside a child component as Vue will warn you in the consol ...

Enroll in a stream of data while iterating through a loop in an Angular application

I encounter a situation where I must subscribe to an Observable, iterate through the response, and then subscribe to another Observable using data from the initial Observable. getTasks(taskType: Observable<any>): void { taskType // Subscribing ...

Explore dual functionality options for a button in Ionic 3

I'm currently developing an app using the Ionic 3 framework. It's a simple calculator app that requires two input fields and a button for calculation. Upon pressing the button, the variables will be computed. Below is my HTML code snippet: <i ...

How can TypeScript generics' properties be made mutable instead of read-only?

Being new to React and Typescript, I encountered an issue with the AlertDismissable class. I am setting the 'show' property when a request is completed. I followed a sample code and made some modifications. Based on the response received, I dyna ...

Changing the content of an HTTP response with the help of RXJS

My API response includes a payload with various details about the queue and its customers. Here is an example of the payload: { "uid": "string", "queue": { "size": 0, "averageWait ...

What is the best way to conduct tests on this React component using Jest?

I'm currently working on increasing the test coverage for a wrapper component in my codebase using jest. Although I haven't been able to identify any specific usage of this component, it's important to ensure that it is covered by tests. M ...

What is the best way to utilize ngForTemplate for wrapping a template?

Using the ngForTemplate in a ListView component for custom templates has proven to be challenging. Modified list-view.component.html: <div class="list-view"> <template ngFor [ngForOf]="items" [ngForTemplate]="template"> </template& ...

Error encountered during password reset in Auth0

I am currently working with Angular 2 and using lock version 10.8 in an attempt to implement a feature that allows users to change their password. I've been experimenting with the following method, which involves calling the Management API. In this me ...

Retrieving values from a nested array within a JSON object

When making a GET request, the JSON object returned has this structure: {"ID":5176, "DateFrom":"8/29/2018", "DateTo":"8/29/2018", "Units":[{"Key":"Value","Key2": "Value2"}] } The issue is with accessing the value of Units[0]. I've attempted the foll ...

Accessing file uploads in Angular 2

<div class="fileUpload btn btn-primary"> <span>Select File</span> <input id="uploadBtn" type="file" class="upload" value="No File Chosen" #uploadBtn/> </div> <input id="uploadFile" placeholder="No File Selected" disable ...

Relentless Recursion in Angular's Parent Component

Take a look at the Stackblitz to replicate the issue Hey there! I have an Angular7 application with a parent component named timesheet, and a child component called row. What I'm trying to achieve is having the parent component, timesheet, dynamicall ...

Angular 4 - Issue: formControlName should always be paired with a parent formGroup directive

Currently, I am incorporating form input fields through a component called - engine-add-contact-form.html <form (ngSubmit)="onSubmit()" [formGroup]="contact_form"> <md-tab-group> <md-tab label="Form"> <ang-form></an ...