Issue
I spent the last 2 hours searching for a solution, and oddly enough, didn't find any. I have worked with sql and nosql databases before but never encountered such a problem. My problem is simple and clear. I have 2 collections : Raw materials & Raw materials stock. Each raw material stock document contains a raw material key. what i want is to the raw material data by its key and join it to the raw material stock list. For eg Raw materials Stock document looks like this
{
"factoryKey": "34",
"quantity": "34",
// i want to get this raw material key data such as name...etc
"rawMaterialKey": "-NDNPe47CDTbjmwGgW_3"
}
Raw material document looks like the following
{
"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 ????
});
}
}
Please help me out i' stuck with that problem. i didn't understand any article solving that problem !
Solution
Since snapshotChanges on AngularFire are Observables, you can take advantage of rxjs to help combine them into 1. You will need to combine both the snapshotChanges of rawMaterialsStockref and rawMaterialsRef.
Here's the steps:
- Query the
raw material_stockcollection. - Once the stock is received, query a
raw_materialdocument based on therawMaterialKeyfield - Combine it with the
raw_material_stockinto an object. - Finally emit the object as an Observable stream
Sample code:
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));
});
Answered By - Lim Shang Yi
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.