uglycode
uglycode

Reputation: 3082

Angular 2 http - filter the observable before returning it

In service I have this defined:

getAllHTTP(): Observable<IUser[]> {
   return this.http.get(`${this.url}/users`)
              .map(res => res.json())
              .catch(err => Observable.throw(err));
}

and in the component:

ngOnInit() {
   const self = this;
   this._uService.getAllHTTP().subscribe(
      function (data) {
        console.log(data);
        self.listOfUsers = data
      },
      (error) => console.error(error)
   );
}

So now I wanted to filter the data before passing the observable to component and I did this:

  getAllHTTP(): Observable<IUser[]> {
     return this.http.get(`${this.url}/users`)
                .map(res => res.json())
                .filter(<IUser>(x) => x.id > 2)
                .catch(err => Observable.throw(err));
  }

and it doesn't work. The x in filter is an actual array, not an item in the array. This is really odd and I think it has nothing to do with RXjs, because it works like it's suppose to in this example: http://jsbin.com/nimejuduso/1/edit?html,js,console,output

So I did some digging and apparently I should be using flatMap. OK, I did that, replaced map with flatMap but now I get this error:

Cannot find a differ supporting object '[object Object]'

So apparently when I subscribe, I used to get an array and now I get one object at a time... Why is Angular2 behaving like that? Or is this RXjs after all?

Upvotes: 0

Views: 14412

Answers (2)

jgranstrom
jgranstrom

Reputation: 586

You are applying a filter on the observable stream, thus filtering events within the stream and not elements within the array which in this case is a single event in the stream.

What you need to do is:

getAllHTTP(): Observable<IUser[]> {
     return this.http.get(`${this.url}/users`)
                .map(res => res.json()
                            .filter(<IUser>(x) => x.id > 2))
                .catch(err => Observable.throw(err));
}

The example you linked is working like that because Observable.from is creating a sequence of values for the observable, rather than a singe value being the whole array. This is why the Observable.filter is working as it does, because the array elements are passing by one at a time. See more details in the docs.

Upvotes: 5

Meir
Meir

Reputation: 14385

It seems like you are asking for a list of user, hence the array. If I got you correctly, you want all users with id > 2:

return this.http.get(`${this.url}/users`)
            .map(res => res.json())
            .map((users: Array<IUser>) => users.filter(user => user.id > 2)
            .catch(err => Observable.throw(err));

Upvotes: 4

Related Questions