Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Observable of array with filter using Angular 5 with RxJS

I'm creating a simple forum.

I'm looking to filter the posts. I have some trouble with .pipe and .filter in RxJS.

I'm trying to:

  • Retrieve the list of in-memory-api posts from api/posts, which when used with http.get it returns an Observable<Post[]>
  • Iterate through each Post in the Observable<Post[]> and filter it so it only selects, says, each post with an id of 1 (only one post with id 1 exists).
  • Log to the console any errors or if the function had success

The filter does not select each individual piece in the Post[] array, but instead selects Post[] itself.

My code:

getPosts(): Observable<Post[]> {

  // Sets the url to the service's postsUrl
  const url = this.postsUrl;

  // The http.get returns an Observable<Post[]>
  return this.http.get<Post[]>(url)
    .pipe(
      filter(
        post: Post => post.id == 1
      ),
      // Log posts were fetched
      tap(posts => console.log('Posts fetched.')),
      // Error handling
      catchError(this.handleError('getPosts', []))
    );
 }

My error:

Property 'id' does not exist on type 'Post[]'

In all examples I've looked at, the filter does not have this issue. I'm thinking it should iterate through all values in the Post[], array, so I can access it as a Post type.


Edit after answer

My final code, based on the accepted answer, looks like this:

In posts.service.ts:

getPosts(): Observable<Post[]> {

  const url = this.postsUrl;

  // Return the observable with array of Posts
  return this.http.get<Post[]>(url)
    .pipe(
      // Log posts were fetched
      tap(posts => console.log('Posts fetched.')),
      // Error handling
      catchError(this.handleError('getPosts', []))
    );

}

In posts.component.ts:

private getPosts(): void {
  this.service.getPosts()
    // Map posts to a filtered version
    .map(
      posts => posts.filter(
        post => post.from_board_id == this.from_board_id
      )
    )
    // Subscribe it
    .subscribe(
      posts => this.posts = posts
    )
  ;
}
like image 851
bugflug Avatar asked Jan 28 '23 19:01

bugflug


1 Answers

Observables are stream of values. You are saying to RXJS that you are going to receive an stream of Post[], in other words, an Array<Post>.

If you wanna filter the array, you may do something like:

 return this.http.get<Post[]>(url).map(posts => posts.filter(post => post.id === 1))
like image 60
Leandro Lima Avatar answered Jan 31 '23 22:01

Leandro Lima