Snackbar-Angular Material Component with Multiple Actions

Abhishek Kumar
3 min readDec 31, 2018

--

Consider a situation in which an user interacts with an application with data state changing at any part of the day. So, pause for a minute and think what can be done to deliver the latest information to the user as the user is currently working on that business application.
Yeah, i know its simple — Notify Him.
But How ? — yes, its the notification on the application with a message.

Many a times, displaying notification is fine with notifying the latest information, but sometimes there are actions to be executed for that notification. Say, either you must respond in positive on the notification action or hide the notification with another cancel action displayed on
the same. See the following image as an instance.

Reply and Archive actions on a notification, Image Taken From

If, you want to have some good knowledge of designing different types of notifications. Here is the link for designing notifications, a medium article for designing notifications.

Recently, i was working on a project that required notifying the user and demanded to have an action on the notification bar to deal with the notification. And my project uses Angular 6 with Angular Material. The notifications are handled using the Angular Material Component — SnackBar. Everything was working fine until the demand increased to have two actions on the notification and SnackBar allows only single action. As in the docs, you can found the line —

Opens a snackbar with a message and an optional action

With no luck after some research, i decided to duplicate my notification SnackBar using a different component and this component will allow multiple actions. It was immediate to move to a component that’s somewhat similar to SnackBar, and i found the BottomSheet component handy in my case, and exploited the BottomSheet to look like a SnackBar. So for multiple action SnackBar, i used and styled the BottomSheet in such a manner to mimic the notification SnackBar as my whole application was dealing with.

Step 1. Generate an event handler responsible for opening the bottomsheet.

Start by putting an event handler that will be responsible for opening the bottomsheet or the customized snackbar with multiple actions. In my case, i am opening the snackbar from mat-list-tem as

(click)=”openBottomSheet(data)”

Step 2. Give implementation for openBottomSheet method.

Import the BottomSheetComponentAsSnackBar component in the corresponding typescript class file and the event handler function will look like as

constructor(private bottomSheet: MatBottomSheet) {}openBottomSheet(dataToBePassedInTheBottomSheet) {
let sheetRef = this.bottomSheet.open(BottomSheetComponentAsSnackBar, {
data: dataToBePassedInTheBottomSheet
});
sheetRef.afterDismissed().subscribe( data => {
// handle your code working according to different actions.
if(data && data.message=='Cancel') {
alert('Cancel was clicked in bottomsheet');
} if(data && data.message=='Status') {
alert('Change Status was clicked in bottomsheet');
}
});
}

Step 3. Create the view for the Customized SnackBar.

See view for the BottomSheetComponentAsSnackBar.html

<div class="bottom-sheet">
<div> Do you want to change status of <span>{{name}}</span> ? </div>
<button mat-button type="button" color="warn" (click)="clearBar()">Cancel</button>
<button mat-button class="change" type="submit" color="warn" (click)="changeStatus()">Change</button>
</div>

Step 4. Style the component accordingly.

BottomSheetComponentAsSnackBar.csscontains the following customized css snippets.

.bottom-sheet {
display: flex;
justify-content: space-between;
align-items: center;
height: 50px;
background-color: #BB3F30;
padding: 10px 20px;
}
.bottom-sheet div {
flex: 1;
color: white;
}
button {
margin-left: 5px;
color: black !important;
}
button.change {
color: white !important;
}
Demo project showing bottomsheet as snackbar
Opened BottomSheet as Snackbar with two Actions

You can handle the BottomSheet backdrop according to the need of the application by toggling the boolean . Handle Bottomsheet Backdrop using hasBackdrop: boolean, in my case i needed that backdrop.

I have written this as an answer to the same question asked on the StackOverflow, find the answer here.

--

--