You can create the Toast component as an Angular service component. The service is a stateless object that contains public functions and maintains the data throughout the life of an application. These functions can be invoked from any Angular component like Controllers, Directives, and more. The service will reduce the code when rendering the same Toast component each time in a different component page. You can create the Toast component as a separate service using ‘@Injectable()’. The following steps explain how to use the Toast component as a separate Angular service: Step #1: Create a separate toast.ts service file using @Injectable and provide a service name as ‘ToastService’. Toast component provides the following methods to define the Angular service: createToast è creates and returns the toast component. showToast/hideToast è shows or hides the toast component using show/hide public method. hideToastAll è hides all the Toast components. You can access these methods within the angular application when required. toast.ts import { Injectable } from '@angular/core'; import { Toast, ToastModel } from '@syncfusion/ej2-notifications'; // Import the toast component @Injectable() export class ToastService { public toastInstance: Toast; constructor() {} // To create the toast component createToast: Function = (element: HTMLElement, model: ToastModel): Toast => { if (!element.classList.contains('e-toast')) { this.toastInstance = new Toast(model, element); } return this.toastInstance }; // To show the toast component showToast: Function = (elemnet: HTMLElement, model: ToastModel) => { this.toastInstance = this.createToast(elemnet, model); this.toastInstance.show(); } // To hide the toast component hideToast: Function = () => { if (this.toastInstance) { this.toastInstance.hide(); } } // To hide the all toast component hideToastAll: Function = () => { if (this.toastInstance) { this.toastInstance.hide('All'); } } }
Step #2: You can inject the service using one of the following options: Option #1: Global service You can inject the service into a root module by specifying providers into @NgModule. app.module.ts import { ToastService } from './toast.service/toast'; @NgModule({ providers: [ToastService] })
Option #2: Local service You can inject the service into a component directly by specifying providers into @Component. app.component.ts import { ToastService } from './toast.service/toast'; @Component({ providers: [ToastService] })
Step #3: You can call the showToast method by clicking the show toast button and the hideToast method is called by clicking the hide toast button using Toast service. You can use the Toast services in the component by the following ways: app.component.ts import { Component, ElementRef, ViewChild } from '@angular/core'; import { ToastService, showToast } from './toast.service/toast'; @Component({ selector: 'my-app', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { @ViewChild("toast") toast: ElementRef; constructor(private toastService: ToastService) { } showBtnClick(e) { this.toastService.showToast(this.toast.nativeElement, { title: 'Toast Sample Header', content: 'Toast Content' }); } hideBtnClick(e) { this.toastService.hideToast();; } }
app.component.html <div style="text-align:center"> <h1> Syncfusion Toast Service </h1> <button class="e-btn" (click)="this.showBtnClick($event)">Show-toast</button> <button class="e-btn" (click)="this.hideBtnClick($event)">Hide-Toast</button> <div id="ej2Toast" #toast></div> </div>
Find the Toast component as an Angular service in this sample. The following screenshot shows the result of the previous code sample.
|
How would I add the position to Top Right as toast placement?
Hi Viswadeep,
You can customize the toast position as per your wish using Position property. You can set the ‘Right’ value to ‘X’ position and ‘Top’ value to ‘Y’ position.
Please find the below demo sample.
Demo Sample: https://ej2.syncfusion.com/angular/demos/#/material/toast/positions
User Guide Documentation link:
https://ej2.syncfusion.com/angular/documentation/toast/position/
Sample:
https://stackblitz.com/edit/toast-as-a-anguar-service-3j3p9g?file=src/app/app.component.ts
Please let us know, if you have any concern on this.
Regards, Ashok
I have a toast with two buttons OK and Cancel. How to return values based on button click to the calling method?
Hi SelvaMani,
Greetings from Syncfusion support,
We have validated your reported query, you can return the values based on the click action performed in the toast. Have prepared a sample that returns which button is clicked in the toast.
Sample: https://stackblitz.com/edit/angular-nvf4zk-ne9ky4?file=package.json
Can you please try out the above solution and let us know if it meets your requirement.
Regards, Indrajith
The ToastService has a design flaw, as it requires you to pass the HTMLElement to each call. This is not how you want to interact with a service from whithin angular!
Hi Balazs,
Greetings from Syncfusion support,
We have validated your reported query. The Toast element is passed for each call since the new ToastObj is created every time with the Show-toast button click. So that the defined toast properties can be applied to the corresponding toast element.
Regards, Indrajith
Created a custom toast service, which uses a globally configurable container, without the need to pass the HTMLElement into each show method.
And also found another issue, which is a toast Design flaw, concretely:
Is there a way to: set a custom angular component (with events) as a content (or a template) and have create multiple instance of that given component (without defining it multiple time on the main HTML)?
Hi Balazs,
Check the below sample for your requirement
https://stackblitz.com/edit/toast-as-a-anguar-service-xbjkrj?file=src/app/toast.service/toast.ts
To close all toast pass 'All' argument in hide method
toastInstance.hide('All');
Regards,
Pandiyaraj
Dear @Pandiyaraj Muniyandi
Hi Balazs,
We regret this inconvenience caused.
We will check the feasibility and update the further details on before July 8, 2020.
Regards,
Pandiyaraj
Hi Balazs,
Yes you could set angular component as content to Toast by passing selector value as content.
// Style display will be dynamically controlled by Toast component
We have prepared sample for your reference, check the below link
https://stackblitz.com/edit/toast-as-a-anguar-service-w5f2d9?file=src%2Fapp%2Fapp.component.ts
Regards,
Pandiyaraj
Hi Balazs,
Ignore the previous update.
Yes, you could set angular component as content to Toast by passing selector value as content.
We have prepared sample for your reference, check the below link
https://stackblitz.com/edit/toast-as-a-anguar-service-w5f2d9?file=src%2Fapp%2Fapp.component.ts
Regards,
Pandiyaraj
The provided sample does not work, if you open up multiple instances of the same toaster, then the result will be a non working select inside.
Also the provided sample requires me to have a DOM element instantiated, so it's not a ng-template.
Let's phrase the original request again:
The use case:
How to achieve that?
If I would not have used the syncfusion Toaster component, I'd create the component dynamically (so possibly bypassing even the TemplateRef approach), and would ensure with CSS that it places well - so that it's attached to the container.
Now as we got the syncfusion bundle and the Toast coponent, the question is: how to achieve the same via the component (as it has some additional features beside the "simple" approach I've described).
Hi Balazs,
We have prepared a sample to meet your desired requirement, check the below link
https://stackblitz.com/edit/angular-cqbaco-mjxugy?embed=1&file=app.component.ts
In the above sample, we have covered your following requirements
Reusable dynamic toast (With new instance)
Pass ng-template (using TemplateRef) as content to Toast (Render custom component into Toast)
Programmatically show a Toast from TS
Regards,
Pandiyaraj
Thank you, it still fails to open up multiple instances of the same type of toast. Also any specific reason that the ToastInstance was also created dynamically and not in the usual way via ToastModel?
Hi Balazs,
ToastModel approach is not suitable to achieve your requirement.
In previous shared sample, if you pass same template again it won't work. So you need to pass different template to show a toast for multiple instance.
Regards,
Pandiyaraj