NgrxStore and Angular - Use the async pipe massively or subscribe just once in the constructor

Neither, you should compose your application as smart and presentation components.

Advantages:

  • All buissness logic on the smart controller.
  • Just one subscribe
  • Reusability
  • The presentation controller has only one responsibility, only to present data and does not know from where the data come from. (loosely coupled)

Answering the last question:

The massive use of async pipe will affect the efficiency, because it will subscribe to every async pipe. You can notice this more if you are calling a http service, because it will call the http request for each async pipe.

Smart Component

@Component({
  selector: 'app-my',
  template: `
      <app-person [person]="person$ | async"></app-person>
`,
  styleUrls: ['./my.component.css']
})
export class MyComponent implements OnInit {

    person$: Observable<Person>;

    constructor(private store: Store<ApplicationState>) {}

    ngOnInit() {
        this.person$ = this.store.select(stateToCurrentPersonSelector);
    }

}

Presentation Component

@Component({
  selector: 'app-person',
  template: `
    <div>{{person.name}}</div>
    <div>{{person.address}}</div>
    <div>{{person.age}}</div>
`,
  styleUrls: ['./my.component.css']
})
export class PersonComponent implements OnInit {

    @Input() person: Person;

    constructor() {}

    ngOnInit() {
    }

}

For more info check:

  • https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0#.u27zmzf25
  • http://blog.angular-university.io/angular-2-smart-components-vs-presentation-components-whats-the-difference-when-to-use-each-and-why/

Another possibility is to use construction like this:

<div *ngIf="person$ | async as per">
    <div>{{ per.name }}</div>
    <div>{{ per.address }}</div>
    <div>{{ per.age }}</div>
<div>

Although for reusable bits of code its possibily better to use presentation component method.

Please note this works in angular 5, not sure about other versions.


You can add ".share()" to the end of any observable declarations. All of your async pipes on an observable will then share the same subscription:

this.name$ = Observable.create(observer => {
  console.log("Subscriber!", observer);
  return observer.next("john")
}).delay(2000).share();

this.httpget$ = http.get("https://api.github.com/").share();

Plunkr demonstrating: https://embed.plnkr.co/HNuq1jUh3vyfR2IuIe4X/