Matt Gween
Matt Gween

Reputation: 177

Angular/RxJS/Typescript thinks my data is an object and not an array?

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!

Upvotes: 1

Views: 539

Answers (2)

OJ Kwon
OJ Kwon

Reputation: 4641

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))

Upvotes: 1

Orlandster
Orlandster

Reputation: 4858

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))

Upvotes: 2

Related Questions