angularfilterrxjspipeconcatmap

rxjs pipeline to filter documents based on conditions and return array


In my Angular service I am trying to write a pipeline that would take a list of documents. Filter them based on some conditions, for example property value must not be null, etc. Then the document that are returned from filter, I want to make Api call and compare the value of a certain property in document. If that passes, continue to next Api call and compare another property with the result of Api call. If that passes, add the document to array.

At the end return the array of these valid documents.

I tried something like this. But not sure if I am on the right track. Please help.

from(listOfDocs).pipe(
  .filter((doc: Doc) => {
    if (!doc.Name) {
      return false;
    }
    return true;
   }),
  concatMap((doc: Doc) => {
        
    return this.myApiService.getDoc(...)
     // how do I get the document returned from Api and do a comparison on a property 
     // value
     // return document if valid otherwise skip to next document
  }),
  concatMap((doc: Doc) => {
        
    return this.mySecondApiCall.getDoc(...)
     // how do I get the document returned from Api and do a comparison on a property 
     // value
     // return document if valid otherwise skip to next document
  })
 // then finally add valid documents to array and return it

Solution

  • If I read your question correctly, something like this might be what you're looking for.

    Each steps filters out any documents that don't meet the filter criteria. This assumes that myApiService and mySecondApiCall always both emit once and then complete. Otherwise you'd need take(1) before the filter to ensure this.

    from(listOfDocs).pipe(
    
      filter((doc: Doc) => !!doc.name),
      concatMap((doc: Doc) => 
        this.myApiService.getDoc(/*...*/).pipe(
          filter(resp => doc.property1 === resp),
          map(_ => doc)
        )
      ),
      concatMap((doc: Doc) => 
        this.mySecondApiCall.getDoc(/*...*/).pipe(
          filter(resp => doc.property2 === resp),
          map(_ => doc)
        )
      ),
      toArray()
    
    ).subscribe(listOfDocs => 
      console.log(`These Docs have passed all 3 filters ${listOfDocs}`)
    );