mlbiche
mlbiche

Reputation: 97

Several Observables in a parent component Vs One Observable in each child component

Let's imagine we have two models Player and World and we want to display a player's information with its world's information within a common view. We get those information through two Observables playerObservable and worldObvservable. We define PlayerComponent (parent), PlayerInformationComponent(child) and WorldInformationComponent(child).

I'm wondering which solution is the most efficient :

Upvotes: 1

Views: 1343

Answers (2)

Vikas
Vikas

Reputation: 12036

Use services to share data
Angular distinguishes components from services in order to increase modularity and reusability. and It's Good Practice to Delegate complex component logic to services

From Angular Style Guide
Do limit logic in a component to only that required for the view. All other logic should be delegated to services.

Do move reusable logic to services and keep components simple and focused on their intended purpose.

Why? Logic may be reused by multiple components when placed within a service and exposed via a function.

Why? Logic in a service can more easily be isolated in a unit test, while the calling logic in the component can be easily mocked.

Why? Removes dependencies and hides implementation details from the component.

Why? Keeps the component slim, trim, and focused.

If your objective is to multicast the data use RXJS's Subject or BehaviorSubject Subject acts as a bridge/proxy between the source Observable and many observers, making it possible for multiple observers to share the same Observable execution.

Advantages of BehaviorSubject over Subject

  1. It will always return the current value on subscription - there is no need to call onnext().
  2. It has a getValue() function to extract the last value as raw data.
  3. It ensures that the component always receives the most recent data.
  4. you can get an observable from behavior subject using the asobservable() method on BehaviorSubject.
  5. Subject vs BehaviorSubject

Service

 private firstResponse=new BehaviorSubject<any>('');
     private secondResponse=new BehaviorSubject<any>('');
          CurrentDatafirst = this.firstResponse.asObservable();
          CurrentDatasecond = this.secondResponse.asObservable();
    getdata(){
       forkJoin([playerObservable, worldObservable])
    .subscribe(([player, world]) => {

    this.firstResponse.next(player),
    this.secondResponse.next(world)
  })
    });
   }

Component1:

ngOnInit()
{
  this.service.CurrentDatafirst.subscribe(//value=>your logic);
  this.service.CurrentDatasecond.subscribe(//value=>your logic)

}

Component2:

 ngOnInit()
    {
      this.service.CurrentDatafirst.subscribe(//value=>your logic);
      this.service.CurrentDatasecond.subscribe(//value=>your logic)

    }

RxJS Subjects for human beings

BehaviorSubject in Angular

Live Demo


-------------------------------------------------------------------------------------

you could also share a single http request for multiple observers using shareReplay operator and take action accordingly.
You must be aware of the fact that http returns a cold observable and When a cold observable has multiple subscribers, the whole data stream is re-emitted for each subscriber. Each subscriber becomes independent and gets its own stream of data

To Avoid Duplication of HTTP Requests shareReplay Operator is used.
Service

 public response$:Observable<any>
    getdata(){
               forkJoin([playerObservable, worldObservable]).pipe(sharReplay(1));
            }

   fetchdata()
           {
              this.response$;
            }

Component1:

 ngOnInit()
    {
      this.service.fetchdata().subscribe(//value=>your logic);


    }

Component2:

    ngOnInit()
    {
      this.service.fetchdata().subscribe(//value=>your logic);


    }

Live Demo

Upvotes: 1

P.S.
P.S.

Reputation: 16394

There is no much difference for your case, I just suggest to decide depending on in which components you need these data, if in parent and children - get in parent and share with child components, if only in child components - you can get data separately right in these children.

BUT

If you have many child components, for example, you repeat something dynamically via *ngFor, I strongly recommend to get the data in parent component and share with children. Otherwise, you will have, for example 50 components and 50 subscriptions, and it will slow down the app very much.

Upvotes: 1

Related Questions