Combining 2 lists in Angular Firebase: A Simple Guide

I have been searching for a solution for the past 2 hours, but unfortunately haven't found one yet. Although I have experience working with both SQL and NoSQL databases, this particular issue is new to me. My problem is quite straightforward: I have two collections - Raw Materials and Raw Materials Stock. Each document in the Raw Materials Stock collection includes a key for the raw material. What I need to do is retrieve the data of the raw material based on its key and join it with the list of raw material stocks. For example: The Raw Materials Stock document looks like this

{
    "factoryKey": "34",
    "quantity": "34",
    //  I want to fetch details such as name for this raw material key
    "rawMaterialKey": "-NDNPe47CDTbjmwGgW_3"
}

The Raw Material document looks like this

{
    "key": "-NDNPe47CDTbjmwGgW_3",
    "code": "R34",
    "name": "RAW2001"
}

Here's my Angular code:

import {Injectable, OnInit} from '@angular/core';
import {LocalStoreService} from '../local-store.service';
import {AngularFirestore} from '@angular/fire/compat/firestore';
import {Router} from '@angular/router';
import { RawMaterialStock } from '../../interfaces/raw-materials/raw-materiels-stock';
import {AngularFireDatabase, AngularFireList, AngularFireObject } from '@angular/fire/compat/database';
@Injectable({
  providedIn: 'root',
})
export class RawMaterialsStockService implements OnInit {

  rawMaterialsStocksRef: AngularFireList<any>;
  rawMaterialsRef: AngularFireList<any>;
  rawMaterialStockRef: AngularFireObject<any>;

  private dbPathStock = '/raw_material_stock';
  private dbPathRawMaterials = '/raw_material';

  constructor(
    private store: LocalStoreService,
    private router: Router,
    private afs: AngularFirestore,
    private db: AngularFireDatabase
  ) {

    this.rawMaterialsStocksRef = db.list(this.dbPathStock);
    this.rawMaterialsRef = db.list(this.dbPathRawMaterials);
  }

  ngOnInit(): void {
  }
  // Methods
  getRawMaterialStockList() {
    return this.rawMaterialsStocksRef.snapshotChanges(['child_added'])
      .subscribe(actions => {
        // WHAT SHOULD I DO HERE ????
      });
  }
}

I'd greatly appreciate any help with this problem. I seem to be stuck and unable to find any resources that address this specific issue!

Answer №1

When using snapshotChanges with AngularFire, you can leverage the power of rxjs to merge them into a single stream. It involves combining the snapshotChanges from both rawMaterialsStockref and rawMaterialsRef.

Follow these steps:

  1. Retrieve data from the raw material_stock collection.
  2. After fetching the stock data, retrieve a document from raw_material based on the field rawMaterialKey
  3. Merge this data with the raw_material_stock into one object.
  4. Finally, emit this combined object as an Observable stream.

For example:

this.rawMaterialsStockref =
      firestore.collection<any>('raw_material_stock');
    this.rawMaterialsRef = firestore.collection<any>('raw_material');

    this.rawMaterialsStockref
      .snapshotChanges(['added'])
      .pipe(
        switchMap((stockSnapshots) => {
          const stockWithRawMaterialsObservables = stockSnapshots.map((s) => {
            const stockId = s.payload.doc.id;
            const stock = s.payload.doc.data();

            return this.rawMaterialsRef
              .doc(stock.rawMaterialKey)
              .snapshotChanges()
              .pipe(
                map((rawMaterialSnapshot) => {
                  const rawMaterial = rawMaterialSnapshot.payload.data() ?? {};

                  return { ...rawMaterial, ...stock };
                })
              );
          });

          return combineLatest(stockWithRawMaterialsObservables);
        })
      )
      .subscribe((stocks) => {
        stocks.forEach((s) => console.log(s));
      });

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

The React Nested Loop Query: Maximizing Efficiency in Data

Learning React has been a challenge for me, especially when comparing it to XML/XPath. In this scenario, I have two arrays simplified with basic string properties... customerList: Customer[] export class Customer { id: string = ""; firstnam ...

Navigate to the login page in Angular 2

Initially, the template login (login.component) needs to be called first. Once the login is complete, then app.component will be loaded. Is it possible to achieve this? And if so, how can I do it? Edited Question: I am already using CanActivate. Apologi ...

Can Angular Interpolation be utilized to showcase Angular components?

I am currently working with an Angular component that relies on a getData method to display results using Angular interpolation in its template. However, I have encountered a scenario where I need a child component to override this method and return a cust ...

Implementing dynamic background images in Angular 4 using div placeholders

Is there a way to include a placeholder or default image while waiting for item.imgSrc to load on the screen? <div class="style" *ngFor="let item of array; <div [style.backgroundImage]="url('+ item.imgSrc +')" class="image">< ...

Adding a parameter to each route by default."

In my Angular app, the route structure is as follows: const routes: Routes = [ { path: ':lang', children: [ { path: 'home', component: HomeComponent }, { path: 'dashboard', component: DashboardC ...

"Error encountered: Array is undefined when using the map and subscribe functions in Ionic

I have developed a service that is supposed to retrieve data from a JSON file and assign it to an array called 'countries', which will be used throughout the application on multiple pages. However, when I call the method getCountries, the countri ...

Extending an interface in TypeScript does not permit the overriding of properties

While working with Typescript, I encountered an issue where I couldn't make a property not required when overwriting it. I have defined two interfaces: interface IField { label: string; model: string; placeholder? ...

Error: Issue with accessing the 'get' property of an undefined value (Resolved issue with incompatible imports not functioning)

Encountering an issue while attempting to execute the karma TS spec file. Despite all modules and imports functioning properly without conflicts, the error persists. I've tried incorporating component.ngOninit() into beforeEach() and it(), but to no a ...

Is it possible to utilize the same selector in two components, but with different template syntax?

Currently, I am working with two components: DetailPage and ListPage. The template for both components is as follows: <my-detailpage> <my-header>{{ text }} </my-header> <my-content>{{ content }} </my-content> </my-detaip ...

The Elusive Glitch: IOS Encounter with Ionic 2

VIEW PROBLEM</p> I am currently developing an Ionic 2 application using Angular 2. Interestingly, I have encountered a peculiar issue that only occurs on one specific page of the app, but specifically on IOS devices. Strangely enough, only the visib ...

Is it possible to access a class with protected/private fields written in TypeScript from outside the class in JavaScript?

Currently, I am delving into TypeScript classes (though my experience with OOP is limited). The following code snippet is extracted from the chapter on classes in https://www.typescriptlang.org/docs/handbook/classes.html Here's the issue at hand: I ...

Angular (4, 5, 6, 7) - An easy guide to implementing slide in and out animations using ngIf

How can you implement a basic sliding animation in Angular4 to show and hide a container element? For example: <div *ngIf="show"> <!-- Content --> </div> Slide the content in (similar to jQuery's slideDown() method) from top t ...

Contrasting Compositions with Generics

Let's consider a scenario where we have an abstract class A and three concrete classes that inherit from it: A1, A2, and A3. There is also another hierarchy tree with an abstract class B and three concrete classes B1, B2, and B3. Each concrete class A ...

Why is the mat-error not appearing within the mat-form field when using custom global validators in Angular Material 6?

While working with Angular Material 6, I encountered an issue where the mat-error validation inside mat-form-field was not displaying properly. However, when I moved the mat-error code after the mat-form-field, it worked as intended. Here is the non-worki ...

Angular 6's subscribe method is causing the UI to not update

I'm currently facing an issue where my component does not refresh the UI after I input data. I always have to manually refresh the page to see the changes. I suspect there might be a problem with the .subscribe method in Angular 6. Previously, when I ...

Angular2: Ways to update components with resolver dependencies?

In my project, I have three separate components, each with its own resolver that retrieves data from distinct APIs. These components all depend on a shared URL provided by a service. My goal is to ensure that when the URL changes, each component refreshes ...

The combination of Vue init and Firebase init led to the creation of intricately nested

My project journey began with Vue CLI, generating the usual package.json, setting up node_modules, and so on. Next, I initiated a Firebase project in the same directory using firebase init, opting for functions. This action birthed a new folder called fun ...

Angular: Comparing the Performance of Switch Statements and Dictionary Lookups

Having trouble deciding between two options for parsing URL parameters? Both seem suboptimal, but is there a better way to handle this situation? If you have any suggestions for a plausible Option #3, please share. Let's assume we are dealing with up ...

NgTemplate Bootstrap is not recognizing my CSS class

I made a CSS adjustment to alter the modal width to 50% instead of 100% of the screen. However, the class modal-content is being duplicated after the modification. https://i.sstatic.net/VZxM6.png https://i.sstatic.net/ahLkn.png CSS .modal-content{ ...

Whenever npm or ng-packagr are updated, the publishing process may attempt to use an incorrect package name or version

Following the transition to [email protected], [email protected], and Angular@13, I am encountering difficulties while attempting to publish a package generated by ng-packager to the npm repository. This is the content of the package.json file: ...