17

I would filter array of objects using RXJS operator filter

I've array of objects like this single one:

    {
      id: string,
      count: number
    }

I would get objects which count > 20

I tried:

  getVotes2(): Observable<Vote> {
    return this._http.get<Vote>(url)
     .pipe(
       map( results => results ),
       filter( result => result.count>20 )
     );
  }

next, without map and I always get all records.

Any ideas?

---------CORRECT CODE------------

getVotes2(): Observable<Vote[]> {
 return this._http.get<Vote[]>(url)
  .pipe(
    map( results => results.filter( r => r.count < 20) )
  )
}
2
  • Did you wanted to use switchMap instead of map here ? Commented Aug 17, 2018 at 15:14
  • I don't know how it exactly works. I need to filter array. Commented Aug 17, 2018 at 15:18

2 Answers 2

50

You're confused on the use of the rx filter operator.

The filter rx operator is NOT the same as the array filter operator. The rx filter operates on a stream and excludes things from THE STREAM that meet a condition, the array filter operator operates on an array and removes items from an array based on a condition.

What you're currently doing is filtering the stream on some undefined "count" property of the array itself, so you're saying "if undefined > 20, then don't let the item through the stream", and one of the quirks of javascript, undefined is not greater than 20 despite being an invalid comparison.

What you need to do is this:

getVotes2(): Observable<Vote[]> {
 return this._http.get<Vote[]>(url)
  .pipe(
    map( results => results.filter(r => r.count > 20) )
  );
}

This way, you use rx Map to perform an operation on the item IN the stream and use the array filter on the item to filter the array.

Edit: as pointed out, the typing also needs to be correct to let typescript know that you're expecting an array of vote objects rather than a single vote object.

Sign up to request clarification or add additional context in comments.

3 Comments

I add type of array <Vote[]> and it's good result. Thanks for explanation!
ah yea, good point, the typing needs to be correct, will update my answer
Just a small add-on (for future readers): both undefined > 20 AND undefined < 20 are always false
0

If http response you are getting is something like

{ 
  data: {
    results: [ {id: 'dd5144s', count: 14}, {id: 'dd51s4s', count: 22}, {id: 'dd5sa44s', count: 8}  ]
  }
}

Then try this:

 return this._http.get<Vote>(url)
   .pipe(
     switchMap( results => results ),
     filter( result => result.count>20 )
   );

Hope this helps.

2 Comments

Http return me an array of objects which I would filter.
Editor show me an error: 'Type Observable<{}> is not assignable to type Observable<Vote>. Type '{}' is not assignable to type 'Vote'. Property 'count' is missing in type '{}''

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.