1

I swear, RxJS is going to be the death of me. I'm pretty sure this is an actual bug with either RxJS, Typescript, or Angular's implementation of either. This works on the RxJS docs page (the javascript console on that page works as an RxJS sandbox):

  new Rx.Observable(observer => observer.next([{
    id: 0,
    name: 'John Doe'
  }, {
    id: 1,
    name: 'Jane Smith'
  }]))
  .map(data => data.filter(item => item.name === 'John Doe'))
  .subscribe(data => console.log(data), err => console.log(err))

But the exact same code is giving me the error Property 'filter' does not exist on type '{}'. in my Angular application. Referencing the data.filter part. data at that point is most definitely an array, so I really can't figure out why it doesn't think so.

I have updated the version of rxjs that the application is using, but that didn't change anything. Any assistance would be greatly appreciated. RxJS is already difficult enough without these inconsistencies!

4
  • That is a typings issue thrown by the typescript compiler. Can you post your angular code? Commented Oct 18, 2017 at 17:33
  • Hmm interesting data should be of type any. It seems to be caused by Rx. Not sure if it is by design. Anyway to fix it you could add type of your data wrapped in the observable, like new Rx.Observable<any[]>. Commented Oct 18, 2017 at 17:54
  • Hrmm.. any reproducibles? Looks fine on plnkr though. plnkr.co/edit/gKe19SNASo4trdpkjKl5?p=preview Commented Oct 18, 2017 at 18:04
  • @arturgrzesiak Thanks. Typing the Observable as <any> fixed the issue. Not ideal, but I've been working on this problem for 3 days and I just don't care anymore. Commented Oct 18, 2017 at 18:28

2 Answers 2

2

You are using the .filter method inside the .map. Both methods iterate over your data, which means data contains an object when you are trying to access it inside the .filter method.

new Rx.Observable(observer => observer.next([
  {id:0, name:'John Doe'},
  {id:1, name:'Jane Smith'}
])).map(data => { 
  // data is an object since map iterates over your array
  return data.filter(item => item.name === 'John Doe')
).subscribe(data => console.log(data), err => console.log(err))

Update:

If you want to filter your data, you don't need the map fucnction.

Simply do this:

new Rx.Observable(observer => observer.next([
  {id:0, name:'John Doe'},
  {id:1, name:'Jane Smith'}
]))
.filter(item => item.name === 'John Doe')
.subscribe(data => console.log(data), err => console.log(err))
Sign up to request clarification or add additional context in comments.

6 Comments

Don't forget to return a value in the map function. I assume you want to return data.filter(item => item.name === 'John Doe');
I don't understand. The RxJS .map operator applies a mapping function to each value emitted from the observable. In this case the value emitted is the array. Not the objects inside the array. Your code is the same as what I provided and causes the same error. How am I supposed to filter the array other than using a .filter inside a .map?
I've updated the answer with a solution which should work for you.
I'm still getting the same error with your updated solution. The second .filter is throwing the error: Property 'filter' does not exist on type '{}'.
oops sry where was my mind. now it's correct. remove the second filter
|
1

This is typescript side issue, not actual code side behavior. If you run this code as is on JS, you can see values are logged via subscription.

Main problem in here is, when you create observable via new Observable() ctor, it is not able to infer type of observable via subscribe function you provided but instead type inference flow from Observable<T> to subscribe function parameter. Cause of those, your observable's type becomes Observable<{}>, and it makes fails to access prototype of array.

Creating Observable via new Observable<Array<{id: number, name: string}>> makes observable operator correctly infer type of values. Or more better, static creation method will provide type inferences for value - like

Rx.Observable.of([{
  id: 0,
  name: 'John Doe'
}, {
  id: 1,
  name: 'Jane Smith'
}])
.map(data => data.filter(item => item.name === 'John Doe'))
.subscribe(data => console.log(data), err => console.log(err))

Comments

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.