Drenai
Drenai

Reputation: 12407

Any reason to use shareReplay(1) in a BehaviorSubject pipe?

I'm using a library that exposes data from a service class using a pretty common BehaviorSubject pattern. The only notable difference with the implementation and what I have seen/used myself is the addition of a pipe with a shareReplay(1) operator. I'm not sure if the shareReplay is required. What effect, if any, does the shareReplay have in this case?

// "rxjs": "^6.3.0"
this.data = new BehaviorSubject({});
this.data$ = this.data.asObservable().pipe(
   shareReplay(1) 
)

Note: I've read a number of articles on shareReplay, and I've seen questions about different combinations of shareReplay and Subject, but not this particular one

Upvotes: 4

Views: 2950

Answers (2)

Adrian Brand
Adrian Brand

Reputation: 21658

Not in your example but imagine if there was some complex logic in a map function that transformed the data then the share replay would save that complex logic being run for each subscription.

const { BehaviorSubject } = rxjs;
const { map, shareReplay } = rxjs.operators;

const bs$ = new BehaviorSubject('initial value');

const obs$ = bs$.pipe(
  map(val => {
    console.log('mapping');
    return 'mapped value';
  }),
  shareReplay({bufferSize:1, refCount: true})
);

obs$.subscribe(val => { console.log(val); });

obs$.subscribe(val => { console.log(val); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.1/rxjs.umd.min.js"></script>

Compare without the share, the map happens twice.

const { BehaviorSubject } = rxjs;
const { map } = rxjs.operators;

const bs$ = new BehaviorSubject('initial value');

const obs$ = bs$.pipe(
  map(val => {
    console.log('mapping');
    return 'mapped value';
  })
);

obs$.subscribe(val => { console.log(val); });

obs$.subscribe(val => { console.log(val); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.1/rxjs.umd.min.js"></script>

Upvotes: 13

Benjamin Barbier
Benjamin Barbier

Reputation: 1

With this pattern (use of shareReplay(1)), the service protects itself from the user using the next() function of the BehaviorSubject while sending the last value of the BehaviorSubject (which would not have been the case without shareReplay(1)).

Upvotes: -1

Related Questions