How to implement behavior subject using service in Angular 8
First create a BehaviourSubject
this._source = new BehaviourSubject<yourType>(initialValue);
this.source = this._source.asObservable();
Define a function to "update" the BehaviourSubject
updateSource(newValue) {
this._source.next(newValue)
}
Now subscribe in your components to the source
this.service.source.subscribe();
Note the behaviourSubject always needs an initial value and emits the last one
DOCS: https://www.learnrxjs.io/subjects/behaviorsubject.html
If you want to share the data from a httpRequest you should use shareReplay() operator instead, you can subscribe to the httpRequest from different components and the request will be made once and the data will be shared
DOCS: https://www.learnrxjs.io/operators/multicasting/sharereplay.html
I'm going to show you a simple way:
@Injectable()
export class ProfileService {
private profileObs$: BehaviorSubject<Profile> = new BehaviorSubject(null);
getProfileObs(): Observable<Profile> {
return this.profileObs$.asObservable();
}
setProfileObs(profile: Profile) {
this.profileObs$.next(profile);
}
}
Now when you update something anywhere in the application, you can set that change by the ProfileService
and each subscriber is receiving the change. I recommend you subscribe in ngOnInit
.
ngOnInit() {
this.profileService.getProfileObs().subscribe(profile => this.profile = profile);
}
Never forget to unsubscribe from the observables to prevent memory leaks!
There are many ways u can do that --> Use a subscription and unsubscribe in ngOnDestroy()
or use another subject and deliver it to takeUntil like this:
unsubscribe$: Subject<boolean> = new Subject();
...
ngOnInit() {
this.profileService.getProfileObs()
.pipe(takeUntil(this.unsubscribe$))
.subscribe(profile => this.profile = profile);
}
ngOnDestroy() {
this.unsubscribe$.next(true);
this.unsubscribe$.complete();
}