1

I am filtering an array of JSON objects, I want to return the found object based on the passed in id argument.

 getClient(id) {
   return this.http.get<any>(' http://localhost:3000/clients')
    .pipe(
      filter(client => client.idNumber === id)
    );
 }

The observer to the above is not triggered and does not receive any data.

  getClient(id)
  .subscribe(
   (data) => {
     // nothing here
   }
  )

The below implementation of getClient achieves what I want.

 getClient(id) {
   return this.http.get<any>(' http://localhost:3000/clients')
    .pipe(
      map(clients => clients.find(client => client.idNumber === id))
    );
 }

I would like to understand, am I using the filter operator the wrong way? And how is my usage different from the one here

1 Answer 1

3

Correct, you are using the rxjs filter operator the wrong way.

Per the docs:

Filter items emitted by the source Observable by only emitting those that satisfy a specified predicate.

In your example, the client value that is getting sent to filter is the array of clients that your http request returned. Then, you are saying "don't emit anything unless client (which is actually an array and has no "idNumber" property is equal to id, which will always be false because unefined !== number

If you want to modify the , you need to use the map operator. The map operator takes what the observable emits, lets you do something (like filter or find in the array), and then return that modified data to subscribers.

Also, if you type your responses property, TypeScript will warn you about this. Instead of this.http.get<any> use this.http.get<Client[]> or some more appropriate type. You would be able to see at compile time that Client[] has no property idNumber.

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

5 Comments

Hey, so is it any different from stackblitz.com/edit/…?
Yes, from([1, 2, 3, 4, 5]) creates an observable that emits 1, then 2, then 3, then 4, then 5. The filter in there says don't emit anything unless its even, so it skips 1, emits 2, skips 3, emits 4, skips 5. Your http request only emits a single value, which is an array of clients. It doesn't emit one value for each client in the array.
Aha..yes I see where I am lacking now :D. Thank you so much for the clarification.
No problem, its confusing sometimes because some of the operators in rxjs have the same names as JS array and object methods. Always log what you are emitting to make sure its actually the type you expect at runtime. Also try and type things properly in your code so you'll get some compile time help as well, but at the end of the day once its running the types are gone so API calls could change the data they send...
Yes I completely concur with that, I have noted that, thanks.

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.