Filtering an Observable (with no duplicates)

I’m filtering an Observable but want to remove any duplicates and undefineds, so I’m hoping to use a Set and some null checks. I’m hoping to only return the dept value.

My first Observable looks like this:

[
    {code: 1, dept: 2, height: 3},
    {code: 1, height: 3}
]

Sometimes there is no dept value so I want to make sure I only return it when it’s there.

Also, I only want to return the departments (with no duplicates) so here’s my code:

myObjects$ = this.myDummyService.getMyObjects() // returns a mock object like above
myDepts$ = this.myObjects$.pipe(
    map((myObjects) => {
        allObjects.filter((myObject:any) => {
            if(myObject.dept!== undefined) {
                return myObject.dept;
            }
        }
    })
    distinct((entity) => entity.dept)

So this works for undefineds (even though there’s probably a more elegant way). But how can I test for dupes? I tried this code but am getting syntax errors:

myDepts$ = this.myObjects$.pipe(map((myObjects) => {
    const allMyObjects = allObjects.filter((myObject:any) => {
        if(myObject.dept!== undefined) {
            return myObject.dept;
        }
    }
    const noDupesDepts = new Set(allMyObjects); 
});

  • The array simply does not exist where (and when) you’re trying to create the set from it.

    – 




  • so the answer is that i cannot remove duplicates using a Set from inside the Observable.

    – 

  • 2

    There’s a time aspect it seems is not being considered. “Removing duplicates” could mean either “remove duplicates from all emissions seen so far” (in which case, the list without duplicates would constantly be changing and will always contain the original value until its first duplicate is emitted), or “remove duplicates from all emissions once all values have been emitted” (in which case, the list is not available until the observable completes).

    – 

  • Thank you, that helps me understand. The filter signature has params for the element passed in and the array itself. (which will help me check if the item is already in there) But when I try and do this, it fails: allObjects.filter((myObject:any) => { if(myObject.dept!== undefined) { return myObject.dept; }), element, arr). Is my syntax incorrect?

    – 




  • I tried adding a distinct() operator (edited code above) that checks for the “dept” property but that’s not working.

    – 




Not sure, but there are a few things that I saw.
I maybe wrong but I guess the map needs to return a value. I changed it a bit :

  myDepts$ = this.myObjects$.pipe(
  filter((myObject: any) => myObject.dept !== undefined), // filters out objects without dept
      map((myObject: any) => myObject.dept), // gets the department
      distinct() // get distinct departments
 );

This should eventually give you only the departments whenever you subscribe to myDepts$.

I am hoping I understood what you are asking for

Leave a Comment