Reputation: 1520
I have a working snackbar, but it is only on each component, I want to add it on my service so I will just call it. This is my sample on my component.ts
import { MdSnackBar, MdSnackBarRef } from '@angular/material';
...
export class EmployeeListComponent implements OnInit {
public toastRef: MdSnackBarRef<any>;
constructor(private _activatedRoute:ActivatedRoute,private router: Router, private http:PMISHttpService, private toast: MdSnackBar) {
ngOnInit() {
this.notify('test');
}
...
notify (text: string) {
this.toastRef = this.toast.open(text, null);
setTimeout(() => {
this.toastRef.dismiss();
}, 5000);
}
...
}
Upvotes: 23
Views: 26929
Reputation: 2225
Here is my working example (Angular 11, Angular Material 11.0.1).
The most important part is to include MatSnackBarModule in the app.module.ts. Also, don't forget to import BrowserAnimationsModule as well.
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
@NgModule({
imports: [
MatSnackBarModule,
BrowserAnimationsModule
...
],
Then, my service looks like this
import { Injectable } from '@angular/core';
import { MatSnackBar } from '@angular/material/snack-bar';
@Injectable({
providedIn: 'root'
})
export class SnackbarService {
constructor(
private _snackBar: MatSnackBar) {
}
error(message: string) {
return this._snackBar.open(message, undefined, {panelClass: ['snackbar-error']});
}
success(message: string) {
return this._snackBar.open(message, undefined, {panelClass: ['snackbar-success']});
}
info(message: string) {
return this._snackBar.open(message, undefined, {panelClass: ['snackbar-info']});
}
}
To define styles, I added these to styles.scss
.mat-simple-snackbar {
font-size: 1.2em;
color: white;
}
.snackbar-error {
background-color: red;
}
.snackbar-success {
background-color: green;
}
.snackbar-info {
background-color: blue;
}
This way, I am now able to call SnackBar from anywhere in the code (including components from other modules). Usage example:
import { Component } from '@angular/core';
import { AuthService } from 'src/app/services/auth/auth.service';
import { SnackbarService } from 'src/app/services/snackbar.service';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.scss']
})
export class LoginComponent {
loginForm: any;
constructor(private authService: AuthService, private snackbar: SnackbarService) { }
onSubmit() {
this.authService.login(this.loginForm).subscribe(res => {
this.snackbar.success('Logged in');
}, e => {
this.snackbar.error('Login failed');
});
}
}
Upvotes: 15
Reputation: 3345
You can easily do this . Please find below the example for the sample which i used in one of my projects and it works perfectly fine
import { Injectable } from '@angular/core';
import {
MatSnackBar,
MatSnackBarConfig,
MatSnackBarHorizontalPosition,
MatSnackBarVerticalPosition,
MatSnackBarRef
} from '@angular/material';
@Injectable()
export class SnackBarService {
snackBarConfig: MatSnackBarConfig;
snackBarRef: MatSnackBarRef<any>;
horizontalPosition: MatSnackBarHorizontalPosition = 'center';
verticalPosition: MatSnackBarVerticalPosition = 'top';
snackBarAutoHide = '1500';
constructor(private snackBar: MatSnackBar) { }
openSnackBar(message) {
this.snackBarConfig = new MatSnackBarConfig();
this.snackBarConfig.horizontalPosition = this.horizontalPosition;
this.snackBarConfig.verticalPosition = this.verticalPosition;
this.snackBarConfig.duration = parseInt(this.snackBarAutoHide, 0);
this.snackBarConfig.panelClass = 'custom-snackbar';
this.snackBarRef = this.snackBar.open(message, '', this.snackBarConfig);
}
}
Now , you only need to inject this service in your component or where ever you want to use it and call openSnackBar() method with the message you want to show.
Hope this helps!!
Upvotes: 10
Reputation: 2336
To have it everywhere, create a service for it. Also you should use the snackbar config for setting duration and make snackbar public:
import {Injectable, NgZone} from '@angular/core';
import {MatSnackBar} from '@angular/material';
@Injectable()
export class CustomSnackbarService {
constructor(
public snackBar: MatSnackBar,
private zone: NgZone
) {}
public open(message, action = 'success', duration = 50000) {
this.zone.run(() => {
this.snackBar.open(message, action, { duration });
});
}
}
Also it needs to be run in ngZone
: https://github.com/angular/material2/issues/9875
Then in the component:
customSnackbarService.open('hello')
Upvotes: 14
Reputation: 15353
If you want a SnackBar to work across your entire app, you should put it into your app.component and communicate with it with a service.
notification.service.ts:
public notification$: Subject<string> = new Subject();
app.component.ts:
constructor(
private notificationService: NotificationService, private snackBar: MatSnackBar
) {
this.notificationService.notification$.subscribe(message => {
this.snackBar.open(message);
});
}
any.component.ts:
this.notificationService.notification$.next('this is a notification');
Upvotes: 22
Reputation: 31
I am using version version": "2.0.0-beta.10", This is what I did to get it working
In ApModule
import { NotificationService } from "./notification/notification.service";
import { MdSnackBarModule } from "@angular/material";
@NgModule({
imports: [
MdSnackBarModule,
FormsModule
],
providers: [WebService, NotificationService]
Create a notification service as suggested in previous post
import { Injectable } from "@angular/core";
import {
MdSnackBar,
MdSnackBarConfig,
// MdSnackBarHorizontalPosition,
// MdSnackBarVerticalPosition,
MdSnackBarRef
} from "@angular/material";
@Injectable()
export class NotificationService {
private snackBarConfig: MdSnackBarConfig;
private snackBarRef: MdSnackBarRef<any>;
private snackBarAutoHide = "5000"; //milliseconds for notification , 5 secs
constructor(private sb: MdSnackBar) {}
openSnackBar(message) {
this.snackBarConfig = new MdSnackBarConfig();
//this.snackBarConfig.horizontalPosition = this.horizontalPosition; only in current version Demo uses very old version . need to upgrade later
//this.snackBarConfig.verticalPosition = this.verticalPosition; only in current version Demo uses very old version . need to upgrade later
this.snackBarConfig.duration = parseInt(this.snackBarAutoHide, 0);
this.sb.open(message, "", this.snackBarConfig);
}
}
Consume service as shown below
this.notify.openSnackBar(message);
Upvotes: 3