Reputation: 2084
I have created a notification service for my application as following :
export class NotificationService {
private subject = new Subject<Notification>();
constructor() {}
getNotification(): Observable<any>{
return this.subject.asObservable();
}
success(title: string, message: string){
this.notif(NotificationType.SUCCESS, title, message);
}
error(title: string, message: string){
this.notif(NotificationType.ERROR, title, message);
}
technicalError(title:string, message: string){
this.notif(NotificationType.TECHNICAL_ERROR, title, message);
}
info(title: string, message: string){
this.notif(NotificationType.INFO, title, message);
}
warning(title: string, message: string){
this.notif(NotificationType.WARNING, title, message);
}
notif(type: NotificationType, title: string, message: string){
this.subject.next(<Notification>{ type: type, title: title, message: message});
}
And this is an example on how I use this service:
this.notificationService.success("Suppression", "L'enregistrement a été supprimée !");
And since I have a component which is shared between all my components which is the header, I have a subscribe for the notification service subject in it's ngOnInit function:
this.notificationService.getNotification().subscribe((notification: Notification) => {
this.notification.create(NotificationType[notification.type], notification.title, notification.message);
});
For the first time I run the application the code inside subscribe function is executed once when I call some notificationService function, but after that the code inside the subscribe function executes multiple times.
How can I solve this ?
Upvotes: 0
Views: 1383
Reputation: 2007
Each time an instance of your Header Component is created, it creates another subscription to your Notification Service. When the Header Component is destroyed, it must clean up its subscriptions. If not, the subscribe block will continue to execute whenever the observable emits a new value.
In general, any component which subscribes to a service should contain an ngOnDestroy lifecycle method which cleans up any subscriptions it has made.
To unsubscribe automatically, you can use a componentDestroyed
Subject along with the rxjs takeUntil
operator. In ngOnDestroy, you emit a value on componentDestroyed
which completes the subscription:
export class HeaderComponent implements OnInit, OnDestroy {
private componentDestroyed = new Subject<any>();
constructor(private notificationService: NotificationService) { }
ngOnInit() {
this.notificationService.getNotification()
.pipe(takeUntil(this.componentDestroyed))
.subscribe(notification => {
// ...
});
}
ngOnDestroy() {
this.componentDestroyed.next();
}
}
Upvotes: 2
Reputation: 39482
You're calling the notif
method from other methods like success
, error
, info
, warning
etc. The notif
method is calling next
on your Subject
which eventually is pushing a new value to the Subject
that you have exposed as an Observable
by calling the asObservable()
method on it.
Make sure that you're not calling the success
, error
, info
, warning
etc. anywhere else in your application. If these methods are called more than once, the subscribe
method will also get called more than once.
Upvotes: 0