4

I have a single Service, which returns a single Observable. Now I'm looking for the correct / most efficient way to get multiple results from this Observable without writing too much code.

  • MyService returns an Observable<Array<Foo>>

  • MyComponent calls myService.getFoos() and should output the first 5 elements from the array, and the total length of the array, and the number of elements not shown.

Here's my current code:

@Injectable()
export class MyService {
  foos = new BehaviorSubject<Array<Foo>>([]);

  getFoos() {
    return this.foos.asObservable();
  }
}



@Component({
  template: `
    Total: {{ totalCount | async }}
    Omitted: {{ (totalCount | async) - (maxFiveItems | async).length }}
    <div *ngFor="let item of maxFiveItems | async">
      {{item.bar}}
    </div>
  `
})
export class MyComponent {
  totalCount: Observable<number>;
  maxFiveItems: Observable<Array<Foo>>;

  constructor(myService:MyService) {
    this.totalCount = myService.getFoos()
        .map(arr => arr.length);

    this.maxFiveItems = myService.getFoos()
        .map(arr => arr.slice(0, 5));
  }
}

The result looks fine, but I'm using the async pipe 4 times. Which (as far as I know) will result in 4 Subscriptions. This shouldn't be necessary at all I guess (?)


Of course I could manually subscribe within the constructor of MyComponent and then live without async pipes. But then I have to take care of unsubscribing myself.

Is there any other way to handle this?

1 Answer 1

4

There's nothing wrong with what you're doing assuming that myService.getFoos() somewhere inside uses share() operator so all your async pipes share the same subscription to the source. If you're using BehaviorSubject as in this example then you're fine.

What you mentioned about subscribing yourself in the constructor is what came to my mind immediately. I don't see manual unsubscription as a problem though.

Sign up to request clarification or add additional context in comments.

4 Comments

I don't understang why you should use share on a BehaviorSubject. Regarding unsubscription, if you manually subscribe to something that can emit more than one value (this is the case for a behavior subject), then you need to unsubscribe. Otherwise you get a memory leak. Basically you would to that implementing the OnDestroy interface in your component.
Appart from that, I agree with you: @Benjamin approach seems perfectly good.
I just read about an upcoming Feature in Angular 4: ngIf with async pipe and let (see: netbasal.com/a-taste-from-angular-version-4-50be1c4f3550 ). This could solve some of these multi-subscription scenarios.
Yes, the new ngIf would be probably the easiest way to do this.

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.