What is the best way to convert Observable<Observable<{...}>[ ]> to Observable<{...}[ ]>?

I am currently working on merging two observable objects into a single observable to access data from both. These observables represent documents from separate collections in a NoSQL database, specifically a Cloud Firestore database. Both collections have a common field with the same value (uid and partnerID). Initially, I created a query to retrieve the first observable object, which returns an Observable<{Object1}[]>. However, when attempting to add code to fetch the second observable object and merge it with the existing one, I end up with an

Observable<Observable<{Object1 merged with Object2}>[]>
.

How can I ensure that the resulting observable is an array containing objects that are a combination of the two retrieved objects from the database?

The ultimate goal is to utilize this combined observable object within my Angular project, leveraging rxjs operators for this purpose.

This is the function within my service without the inclusion of the second observable object:

queryMatches(fieldNameOfRole, boolValueOfAccepted) {
    return this.authService.user$.pipe(
      switchMap(user => {
        return this.angularFirestore
          .collection('matches', ref => ref.where(fieldNameOfRole, '==', user ? user.uid : '')
            .where('accepted', '==', boolValueOfAccepted))
          .snapshotChanges()
          .pipe(
            map(actions => {
              return actions.map(a => {
                const data = a.payload.doc.data() as Match;
                const matchId = a.payload.doc.id;
                return { matchId, ...data };
              });
            })
          );
      })
    );
  }

As a result, the following is returned:

(method) MatchStoreService.queryMatches(fieldNameOfRole: any, boolValueOfAccepted: any): Observable<{
    initiatorID: string;
    partnerID: string;
    matchedOffer: string;
    accepted: boolean;
    id: string;
}[]>

Here is how I attempted to combine it with the second observable object:

queryMatches(fieldNameOfRole, boolValueOfAccepted) {
    return this.authService.user$.pipe(
      switchMap(user => {
        return this.angularFirestore
          .collection('matches', ref => ref.where(fieldNameOfRole, '==', user ? user.uid : '')
            .where('accepted', '==', boolValueOfAccepted))
          .snapshotChanges()
          .pipe(
            map(actions => {
              return actions.map(a => {
                const data = a.payload.doc.data() as Match;
                const matchId = a.payload.doc.id;
                return { matchId, ...data };
              });
            })
          );
      }),
      map(matches => {
        return matches.map(match => {
          return this.userStoreService.getUserById(match.partnerID).pipe(
            map(user => {
              return { ...match, ...user };
            })
          );
        });
      })
    );
  }

Following this approach, the following output is generated:

(method) MatchStoreService.queryMatches(fieldNameOfRole: any, boolValueOfAccepted: any): Observable<Observable<{
    uid: string;
    firstname: string;
    lastname: string;
    dateOfBirth: Date;
    sex: string;
    city: string;
    activities: string[];
    offers: string[];
    mail?: string;
    ... 4 more ...;
    matchId: string;
}>[]>

UPDATE

The implementation of getUserById():

getUserById(uid) {
    return this.angularFirestore
    .collection<any>(`users`)
    .doc<User>(uid).valueChanges();
   }

Answer №1

To implement this functionality, simply utilize the forkJoin operator in the following manner:

 map(matches => {
        return combineLatest(matches.map(match => {
          return this.userStoreService.getUserById(match.partnerID).pipe(
            map(user => {
              return { ...match, ...user };
            })
          );
        }));
      })

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

Guide to releasing a NestJs library on npm using the nrwl/nx framework

Struggling with creating a publishable NestJS library using NX. Despite reading numerous documentations, I still can't figure it out. I've developed a NestJS library within an NX monorepository and now I want to publish just this library on NPM, ...

The module has defined the component locally, however, it has not been made available for

I have developed a collaborative module where I declared and exported the necessary component for use in other modules. import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { DateslideCompone ...

Utilize the value of one variable to determine access to another variable in Javascript

I am working with several boolean variables and I want to create a new variable that keeps track of the most recently changed boolean variable. This way, every time a new boolean variable is modified, I can toggle the previous one. If you have any ideas o ...

Encountering build errors in .xproj file when working with Type Script in ASP.Net Core

I recently started working on a new ASP.Net Core project and decided to integrate Angular 2 and Type Script by following a blog post tutorial. However, upon adding a Type Script file to my project, I encountered several build errors from the xproj file. h ...

How can Multer library be effectively utilized to manage exceptions in NestJS controllers?

While working on creating a service to upload specific files from a Post multipart/form-data request, I came across an easy way to validate the fields count and name sent using the FileInterceptor decorator from @nestjs/platform-express. However, I'm ...

Leverage functionalities from the rxjs npm package within an Angular application without the need for npm install

In the midst of updating my Angular 4 application to use rxjs version 6.3+, I discovered that many changes in rxjs are causing issues with my existing codebase. One of the new features we need to implement requires this update, but it's proving to be ...

I'm having trouble getting any data to emit when I subscribe to a state service subject that stores a hovered element. What could I be missing?

I am currently working on a project that involves a calendar, a hover directive, and a stateful service for communication. Here's a simplified representation of my work so far: https://stackblitz.com/edit/stackblitz-starters-kvzyvy?file=src%2Fmain.ts ...

Creating a Powerful Application with Typescript and NodeJS

Currently, I am attempting to utilize Got with Typescript and ESM. With Got being written in Typescript itself, I anticipated a seamless integration. Alas, even after diligently following this comprehensive guide authored by the creator of Got, I am unable ...

Tips for utilizing a ternary operator to set a className in an element

I'm in the process of developing a website using React and Next.js. One of the components on my site is section.tsx, which displays a subsection of an article based on the provided props. I'm looking to add an 'align' property to this c ...

Issue with Datepicker validation in Angular 5 and Angular Material

I have implemented the most recent version of Angular and Angular Material. I am facing an issue with a datepicker where the validation requirements are not being met as expected. The documentation states that the required attribute should work by default, ...

Setting default parameters for TypeScript generics

Let's say I define a function like this: const myFunc = <T, > (data: T) => { return data?.map((d) => ({name: d.name}) } The TypeScript compiler throws an error saying: Property 'name' does not exist on type 'T', whic ...

How do I condense nested keys in TypeScript?

If I have two types defined in TypeScript: interface Foo { bar: string; } interface Baz { foo: Foo; } Is it possible to flatten the Baz type in TypeScript (e.g. type FlatBaz = Flatten<Baz>), so that the signature appears similar to this? inte ...

Extracting data from a JSON object using Angular 2

I need advice on the most efficient way to handle JSON within my angular2 application. The JSON data I am working with includes: { "rightUpperLogoId": { "id": 100000, "value": "" }, "navbarBackgroundColorIdCss": { "id" ...

JavaScript cannot determine the length of an array of objects

I'm encountering an issue with an array of objects named tagTagfilter. When I log it in the browser, it doesn't immediately show the correct length value inside. tagTagFilter: TagFilter = { filterName: 'Tag', tags: [] ...

Include a parameter in a type alias

Utilizing a function from a library with the following type: type QueryFetcher = (query: string, variables?: Record<string, any>) => Promise<QueryResponse> | QueryResponse; I aim to introduce an additional argument to this type without mod ...

Embedding Globalize.js into an Angular component

Hey there! I'm currently working on building an Angular 4 application that needs to support L10n. I've decided to incorporate globalize into my project. Below is a snippet of my App component: import { Component, OnInit } from '@angular/c ...

Different Approaches for Handling User Interactions in Angular Instead of Using the Deferred (Anti-?)Pattern

In the process of developing a game using Angular, I have implemented the following mechanics: An Angular service checks the game state and prompts a necessary user interaction. A mediator service creates this prompt and sends it to the relevant Angular c ...

What is the best way to modify the color of a table cell in Typescript with *ngFor loop?

I have an image located at the following link: https://i.sstatic.net/rxDQT.png My goal is to have cells with different colors, where main action=1 results in a green cell and action=0 results in a red cell. Below is the HTML code I am working with: & ...

Placeholder variable not specified in radio buttons

I am currently facing challenges applying validations to radio buttons in Angular. Normally, I create a #templateRefVariable on the input for other input types, which allows me to access the NgControl and use properties like touched. My goal is to set the ...

Incompatible parameter type for the Angular keyvalue pipe: the argument does not match the assigned parameter type

I need to display the keys and values of a map in my HTML file by iterating over it. To achieve this, I utilized Angular's *ngfor with the keyvalue pipe. However, I encountered an error when using ngFor: The argument type Map<string, BarcodeInfo ...