0

I have 2 firebase list Raw Materials & Stock. The stock list contains objects with a raw material key. i use that key to fetch the raw material. I'm getting all the stock list , then when i iterate through each object in the list to join the raw material, the problem is that the observable returns only the first object. meaning, it doesn't iterate through all the list. here's my code

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


  private dbPathStock = '/raw_material_stock';

  constructor(
    private db: AngularFireDatabase,
    private rawMaterialService: RawMaterialsManagementService
  ) {
    this.rawMaterialsStocksRef = db.list(this.dbPathStock);
  }

getRawMaterialStockList() {
  
   const rawData = this.rawMaterialsStocksRef.valueChanges().pipe(
      map(rawMaterialsStocks =>
        rawMaterialsStocks.map(stock => ({
         ...stock
        }))
      ),
      switchMap(stockArr => from(stockArr)), 
      // gives the following 
      // { "factoryKey": "34""quantity": "34", "rawMaterialKey": "-NDNPe47CDTbjmwGgW_3"}
      // { "factoryKey": "20", "quantity": "20", "rawMaterialKey": "-NDIjiVqKP-lLwJGwmic"}
      switchMap(stock =>
        // this service i use to fetch each raw material based on its key
        this.rawMaterialService.getRawMaterial(stock.rawMaterialKey).valueChanges()
          .pipe(
            map(rawMaterial => {
              return { ...stock, ...rawMaterial }
            })
          )
      ),
    );
   
   rawData.subscribe()
}

here is the result i'm getting

{
    "factoryKey": "20",
    "quantity": "20",
    "rawMaterialKey": "-NDIjiVqKP-lLwJGwmic",
    "code": "KLL2311",
    "name": "Material 03"
}

as you can see i only got one successful join, despite the array containing multiple objects !

PLEASE HELP ME OUT I SPENT THE 3 DAYS TRYING EVERYTHING, DIDNT WORK OUT !

enter image description here

1 Answer 1

1

switchMap

the switch in switchMap is meant to denote the extra behaviour of the operator. Switch means "drop the previous observable if it's active, switch to this one instead."

concatMap means "If there's still an active obserable, put this in the queue to be run as soon as the previous observables complete"

mergeMap means "I don't care if or how many previous observables are running at the moment. Subscribe to them all and emit whatever any source observable emits"


Change your switchmap to one of the other two

mergeMap(stock => this.rawMaterial..........
  ........

An Aside

I suggest you pick one programming style. Your code has both

map(stock => ({
  ...stock
}))

map(rawMaterial => {
  return { ...stock, ...rawMaterial }
})

Option one:

map(stock => ({
  ...stock
}))

map(rawMaterial => ({ 
  ...stock, ...rawMaterial 
}))

option 2:

map(stock => {
  return { ...stock }
})

map(rawMaterial => {
  return { ...stock, ...rawMaterial }
})

Mixing them so both are in the same small segment of code makes it so much harder to skim through code coherently.

Update # 1

Using forkJoin to return an array of results in parallel.

mergeMap(stockArr => forkJoin(stockArr.map(stock =>
  this.rawMaterialService
    .getRawMaterial(stock.rawMaterialKey)
    .valueChanges()
    .pipe(
      map(rawMaterial => ({ ...stock, ...rawMaterial }))
    )
)))
Sign up to request clarification or add additional context in comments.

3 Comments

Buddy , from the bottom of my heart, THANK YOU ! BIG BIG THAN YOU ! i posted 4 times the problem no one took the time to help. I'm happy to know that there are still people willing to help. THANK YOU AGAIN. IT WORKS LIKE A CHARM <3
One more simple question, the merge his returning objects separatly, is there's a way to put them all in a single Array !?
Sure, I've made an update to my answer

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.