Simple filter on array of RXJS Observable

后端 未结 4 753
独厮守ぢ
独厮守ぢ 2020-12-12 19:21

I am starting my project with Angular2 and the developers seem to recommend RXJS Observable instead of Promises.

I have achieved to retrieve a list of elements (epic

相关标签:
4条回答
  • 2020-12-12 19:34

    You'll want to filter the actual array and not the observable wrapped around it. So you'll map the content of the Observable (which is an Epic[]) to a filtered Epic.

    getEpic(id: string): Observable<Epic> {
      return this.getEpics()
         .map(epics => epics.filter(epic => epic.id === id)[0]);
    }
    

    Then afterwards you can subscribe to getEpic and do whatever you want with it.

    0 讨论(0)
  • 2020-12-12 19:34

    You can do this using the flatMap and filter methods of Observable instead of the JS array filter method in map. Something like:

    this.getEpics() 
        .flatMap((data) => data.epics) // [{id: 1}, {id: 4}, {id: 3}, ..., {id: N}]
        .filter((epic) => epic.id === id) // checks {id: 1}, then {id: 2}, etc
        .subscribe((result) => ...); // do something epic!!!
    

    flatMap will provide singular indices for filtering and then you can get on with whatever happens next with the results.

    If TypeScript throws a error indicating you can't compare a string and a number regardless of your use of == in the filter just add a + before epic.id in the filter, per the Angular docs:

        .flatMap(...)
        .filter((epic) => +epic.id === id) // checks {id: 1}, then {id: 2}, etc
        .subscribe(...)
    

    Example:

    https://stackblitz.com/edit/angular-9ehje5?file=src%2Fapp%2Fapp.component.ts

    0 讨论(0)
  • 2020-12-12 19:37

    You have to subscribe on Observables to get the data, since http calls are async in JavaScript.

    getEpic(id: number, callback: (epic: Epic) => void) {
        this.getEpics().subscribe(
            epics: Array<Epic> => {
                let epic: Epic = epics.filter(epic => epic.id === id)[0];
                callback(epic);
            }
        );
    }
    

    You can call that method then like this:

    this.someService.getEpic(epicId, (epic: Epic) => {
        // do something with it
    });
    
    0 讨论(0)
  • 2020-12-12 19:42

    original answer with a fix: Observables are lazy. You have to call subscribe to tell an observable to send its request.

      getEpic(id:number) {
        return this.getEpics()
               .filter(epic => epic.id === id)
               .subscribe(x=>...);
      }
    

    Update to Rxjs 6:

    import {filter} from 'rxjs/operators';
    
    getEpic(id:number) {
            return this.getEpics()
                   .pipe(filter(epic => epic.id === id))
                   .subscribe(x=>...);
          }
    
    0 讨论(0)
提交回复
热议问题