Reputation: 387
I am trying to use a <p-toast>
in my landing page to display notification messages when users login.
<p-toast position="top-center" key="tc"></p-toast>
The messages are then declared in my components.
ngOnInit() {
// add toasts
this.messageService.addAll([
{key: 'tc', severity: 'info', summary: '30 Nov 2020', detail: 'Important message 1'},
{key: 'tc', severity: 'info', summary: '30 Nov 2020', detail: 'Important message 2'}
]);
// do other stuff
}
This doesn't work. To confirm that it is not a problem with my toast or messages, I placed the messages inside an onClick()
event on the page and manually triggered it, which does work.
How do I get the Toasts to trigger on page load instead?
Upvotes: 5
Views: 3595
Reputation: 21
I believe that anytime you fire off some task such as this from the ngOnInit, for example a toast message or other async call that need to wait for the Init to finish you can put your call right inline with the rest of your code as long as you use setTimeout. The ngAfterInit is not needed. You can thank (or curse) single threaded JavaScript for that.
Upvotes: 0
Reputation: 13964
You have to send the messages once the view is initialized.
However, by triggering the messages in the ngAfterViewInit
hook, you might get an ExpressionChangedAfterItHasBeenCheckedError
.
Here are solutions to avoid this error:
First solution is using a setTimeout
call to send the messages once everything is initialized.
Here is a simple Stackblitz example
ngAfterViewInit() {
setTimeout(() => {
this.messageService.addAll([
{key: 'tc', severity: 'info', summary: '30 Nov 2020', detail: 'Important message 1'},
{key: 'tc', severity: 'info', summary: '30 Nov 2020', detail: 'Important message 2'}
]);
})
}
Another solution is to force change detection using the ChangeDetectorRef
(see this article):
constructor(private messageService: MessageService, private cd: ChangeDetectorRef) { }
ngAfterViewInit() {
this.messageService.addAll([
{key: 'tc', severity: 'info', summary: '30 Nov 2020', detail: 'Important message 1'},
{key: 'tc', severity: 'info', summary: '30 Nov 2020', detail: 'Important message 2'}
]);
this.cd.detectChanges()
}
Upvotes: 7
Reputation: 6283
Try using the AfterViewInit
The issue might be because the HTML is not yet rendered so try the following. This is an Angular Life Cycle hook that is only fired when the HTML has been initialized.
Be sure to add it to the class you are using it in like in the code snippet below, continue to use the ngOnInit
for other logic that does not require HTML to be initialized and accessable.
class MyComponent implements AfterViewInit, ngOnInit {
ngAfterViewInit() {
this.messageService.addAll(
[{key: 'tc', severity: 'info',
summary: '30 Nov 2020', detail: 'Important message 1'},
{key: 'tc', severity: 'info',
summary: '30 Nov 2020', detail: 'Important message 2'}]);
}
ngOnInit() {
//for other logic that does not require the HTML to be initialized.
}
}
If you are having any issues with ExpressionHasChangedAfterItHasBeenCheckedError
then you could alternatively use a different life cycle hook that looks for the view to be initialized.
This would be AfterContentInit and would be used exactly the same as the above example. Whichever works best for you given example. If the easiest solution is to setTimeout then go with that if it causes you no other issues. Would suggest using Angular to your advantage though whilst using the framework.
Upvotes: 5