Skip to content

Instantly share code, notes, and snippets.

@mrgoos
Last active March 3, 2022 09:05
Show Gist options
  • Star 29 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save mrgoos/8bffca32eef7ae6c143b99d069145651 to your computer and use it in GitHub Desktop.
Save mrgoos/8bffca32eef7ae6c143b99d069145651 to your computer and use it in GitHub Desktop.
Use primeNg GrowlModule globally through a service
<p-growl [value]="msgs"></p-growl>
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Message } from 'primeng/primeng';
import { NotificationsService } from './notifications.service';
import { Subscription } from 'rxjs/Subscription';
@Component({
selector: 'app-notifications',
templateUrl: './notifications.component.html',
styleUrls: ['./notifications.component.css']
})
export class NotificationsComponent implements OnInit, OnDestroy {
msgs: Message[] = [];
subscription: Subscription;
constructor(private notificationsService: NotificationsService) { }
ngOnInit() {
this.subscribeToNotifications();
}
subscribeToNotifications() {
this.subscription = this.notificationsService.notificationChange
.subscribe(notification => {
this.msgs.length = 0;
this.msgs.push(notification);
});
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
type Severities = 'success' | 'info' | 'warn' | 'error';
@Injectable()
export class NotificationsService {
notificationChange: Subject<Object> = new Subject<Object>();
notify(severity: Severities, summary: string, detail: string) {
this.notificationChange.next({ severity, summary, detail });
}
}
import { NotificationsService } from 'PATH_TO_NOTIFICATIONS_SERVICE';
....
....
constructor(private notificationsService: NotificationsService) { }
....
....
ngOnInit() {
this.notificationsService.notify('info', 'some component', 'ngOnInit was called!');
}
....
....
//instantiate the notification component
<app-notifications></app-notifications>
//just import the service in order to provide it
....
....
import { NotificationsService } from './notifications/notifications.service';
....
....
@NgModule({
imports: [
CommonModule
...
],
declarations: [
TopComponent
],
providers: [NotificationsService]
})
export class TopModule {
}
@xtoff
Copy link

xtoff commented Apr 25, 2017

thanks for this code.. saved me some time :)

@andrei-ivanov
Copy link

thank you as well :)

@bamba
Copy link

bamba commented May 31, 2017

Thanks. I'm unable to make the notification to hide. is it just me?

@davisb10
Copy link

Thanks so much! Exactly what I was looking for.

@sairam0903
Copy link

Thank you so much for the service, this is what I exactly have in my mind. Incase if the messages are sticky, just edit this line this.msgs.length = 0; to this.msgs= []; in notifications.component.ts, as mentioned in the documentation.

@oidacra
Copy link

oidacra commented Aug 15, 2017

you make my day..

@rekoch
Copy link

rekoch commented Oct 7, 2017

thanks a lot for your work. I had also the case, that I would like to have sticky or no-sticky. So I updated your version just a little bit, if someone ist interested.

notification.component.ts

  • added isSticky and lifeTime property
  • cast notification object
  • get properties out of service call
  • instead of this.msgs.length = 0 you need to empty it with a new array. Otherwise the growl primeng does not work properly

isSticky:boolean = false; lifeTime:number = 3000; subscribeToNotifications() { this.subscription = this.notificationsService.notificationChange .subscribe(notification => { let notificationObject = <NotificationsComponent> notification; this.isSticky = notificationObject.isSticky; this.lifeTime = notificationObject.lifeTime; this.msgs = []; this.msgs.push(notification); }); }

notifications.component.html
<p-growl [(value)]="msgs" [sticky]="isSticky" [life]="lifeTime"></p-growl>
notification.service.ts

  • optional parameter for notify-function to add isSticky and lifetime

notify(severity: Severities, summary: string, detail: string, isSticky?:boolean, lifeTime?:number) { this.notificationChange.next({ severity, summary, detail, isSticky, lifeTime });

Sorry, didn't figure out how to to format it better....

I made a fork if you like to see it cleaner.

@rullymartanto
Copy link

rullymartanto commented Oct 18, 2017

Great code,.. Thanks :D

@filosofisto
Copy link

Great solution, thanks

@filosofisto
Copy link

I detected a problem, maybe in my code:
Growl show message just in first time.
Others notification, simple does not works.

Any body passed by this problem:?

@mleegwt
Copy link

mleegwt commented Jan 9, 2018

The MessageService exists within PrimeNG for that same reason.

@HermenOtter
Copy link

@mleegwt the MessageService doesn't work for with my project for some reason.

@riva-dev
Copy link

Thanks, great code.
@filosofisto use sairam0903's answer

@changhuixu
Copy link

@filosofisto, same problem here. Only works for the first time.
I step in, and the msg array correctly gets new value. Not sure why the growl doesn't show the new message

@salmankazmi
Copy link

salmankazmi commented May 10, 2018

Somehow the notification disappears when a different route is activated. Tried to fix it with setTimeout, but this does not seem like an appropriate solution. Any thoughts on how to make it visible inter-route?

@chaliaga
Copy link

chaliaga commented May 23, 2018

I have the same problem @salmankazni. Did you know how disappear the message?

@kwiniarski97
Copy link

kwiniarski97 commented Jul 17, 2018

@salmankazmi @chaliaga you got to set <p-growl **[(value)]="msgs"**></p-growl> It didn't work for me until I made two-way binding.
And also:
this.subscription = this.notificationsService.notificationChange
.subscribe(notification => {
this.msgs = [];
this.msgs.push(notification);
});

@yasstou
Copy link

yasstou commented Jul 18, 2018

If you look in the documentation for growl in change detection section :

Change Detection
In case messages are provided via the value property instead of service, growl either uses setter based checking or ngDoCheck to realize if the messages has changed to update the UI. This is configured using the immutable property, when enabled (default) setter based detection is utilized so your changes such as adding or removing a record should always create a new array reference instead of manipulating an existing array as Angular does not trigger setters if the reference does not change. For example, use slice instead of splice when removing an item or use spread operator instead of push method when adding an item. On the other hand, setting immutable property to false removes this restriction by using ngDoCheck with IterableDiffers to listen changes without the need to create a new reference of data. Setter based method is faster however both methods can be used depending on your preference. Note that immutable property also defines how Growl treats the value, for example when immutable is enabled removing a message does not mutate the original value but creates a new array.

So you either use the above code as is with [immutable]="false" or leave [immutable]="true" (default) and replace push with spread operator this.growl = [...this.growl , notification]

@hoffmast
Copy link

hoffmast commented Aug 21, 2018

@HermenOtter, The PrimeNG docs are not great for implementing their messaging service. In a further up component (e.g. app.component), you need to add the message service as a provider, add the service in the constructor, and then add a growl component in your HTML which references your component's instance of the service, such as is shown here:
https://stackoverflow.com/questions/50410239/angular-2-primeng-message-service-not-showing-message

For me, PrimeNG's built in messaging service did not work until I followed these steps, at least.

@digeomel
Copy link

digeomel commented Sep 6, 2018

@hoffmast I am trying to do what you described with the Toast component and the MessageService, as described in the (poor) documentation (https://www.primefaces.org/primeng/#/toast).
So, as you said, the MessageService is defined as a provider in my app component, the toast component is in the HTML of the app component as well, but I cannot see how to link it to a particular component further down in the hierarchy.

It goes without saying that I don't want to add the toast component on every single component's template that is using it. I want to add it once in one component (e.g. the app component) and reference it from there, pretty much as it's done in this example. But this example uses the NotificationService, subscriptions, and messages, not the MessageService, which, according to the documentation at least, should not require any such extra steps.

What am I missing?

@rahulmatty
Copy link

rahulmatty commented Oct 1, 2018

@MrGoss @filosofisto, :- Getting this error. Please suggest.
'app-notifications' is not a known element:

  1. If 'app-notifications' is an Angular component, then verify that it is part of this module.
  2. If 'app-notifications' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message. ("

@chaliaga
Copy link

chaliaga commented Oct 5, 2018

@MrGoss @filosofisto, :- Getting this error. Please suggest.
'app-notifications' is not a known element:

1. If 'app-notifications' is an Angular component, then verify that it is part of this module.

2. If 'app-notifications' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message. ("

Hi, @rahulmatty Did you import the module on your app.module.ts?

@jsilveira2
Copy link

Hello, what did you mean by 'top-component.html', because if it is the 'app.component.html' and you put the tag in there. If you try to use in other modules will not work. Right?

Sorry for my bad english.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment