Native Web Push Notifications with Angular 2

The Notifications API allows web pages to control the display of system notifications to the end user — these are outside the top-level browsing context viewport, so therefore can be displayed even the user has switched tabs or moved to a different app. The API is designed to be compatible with existing notification systems across different platforms.
- Mozilla

The Notifications API has been available for some browsers for a while now, and with Angular 2’s recent promotion to Release Candidate (yay!), I thought bringing this powerful API to the Angular world in the form of a library, would make this API more accessible and reusable for developers. Enter ng2-notifications.

Demo

In the following demo, notifications can be customized and displayed using ng2-notifications. Give it a try!

http://embed.plnkr.co/yCEvSre4Kav5t1RYVx1I/

Getting Started

In order to add ng2-notifications to your project, a simple npm install and an module import can get your there pretty fast.

npm install ng2-notifications --save

The import statement can be included in any Angular 2 component.

import { PushNotificationComponent } from 'ng2-notifications';
@Component({
...
directives: [PushNotificationComponent]
})

Now the notification directive can be used inside the component’s template, like this:

<push-notification 
title="Getting Started"
body="A simple npm install can get you there"
icon="https://goo.gl/3eqeiE">
</push-notification>

The Syntax

One of Angular 2’s most powerful features is its declarative markup. With ng2-notifications, a push notification can be written in Angular 2 with the use of literals or my personal favorite; data binding.

<push-notification 
title="notification.title"
body="notification.body"
icon="notification.icon">
</push-notification>

Where in the component’s class, a notification property would look like this:

export class AppComponent {
public notification: any = {
title: 'New Angular 2 Library!',
body: 'ng2-notifications',
icon: 'https://goo.gl/3eqeiE'
};
}

Not too bad, huh?

Other data properties include:

{
tag: string, // optional, no default value
dir: string, // defaults to 'auto', options: ['ltr','rtl']
data: any, // optional, no default value
lang: string // defaults to browser's language, ['en-US', ...]
}

Building the Library

The ng2-notifications library is just a wrapper for the native Web Notifications API. It abstracts and simplifies the process of requesting the user’s permission for notifications and exposes a predictable and easy to use API in the form of an Angular 2 Component.

@Directive({
selector: 'push-notification'
})

You may wonder, why not use a component instead? Well, a component is just a directive + a view, and in this case a view is not required since the UI is completely handled by the browser. That’s one of the reasons why notifications will look slightly different in every browser.

Additionally, the library adds two useful properties: [closeDelay] and [when]. The close delay does exactly what you are thinking, it closes the notifications after x amount of milliseconds. The when property is used to activate the notification given a boolean expression. Think of it as an ng-show.

Understanding Angular 2’s Directive lifecycle is crucial for showing and closing notifications at the right time: when the directive compiles, when data properties changes and when the directive is removed from its parent component.

import {
Directive,
EventEmitter,
OnInit,
OnChanges,
OnDestroy,
Input,
Output
} from ‘@angular/core’;

From the import statement above we can see three very important Angular APIs that can help us hook into certain Directive’s states by implementing these into our Directive’s class definition.

export class PushNotificationComponent implements 
OnInit, OnChanges, OnDestroy {
...
}

By looking at Angular 2’s new Directive API, it was obvious the @Input and @Output API could be leveraged for bidirectional communication. Some of the inputs and outputs can be defined in the following manner:

@Input() public title: string;
@Input() public body: string;
@Input() public icon: string;
@Output() public onClick: EventEmitter<any> = new EventEmitter();
@Output() public onClose: EventEmitter<any> = new EventEmitter();

These inputs and outputs are what enables us to read the data properties and execute callbacks after events fire. The latter can be expressed like this on the markup side:

<push-notification 
...
(click)="notification.action($event)">
</push-notification>

These are just a few of the crucial parts for building a Directive in Angular 2. For the full source code, check out the project on GitHub.

Check On GitHub

Browser Support

Browser support plays a big part on the potential use of any new browser API. Currently, the browser support for Web Notifications is looking very promising. There is full support for desktop browsers like Chrome, Firefox, Safari, Opera and Edge 14. On the mobile browser side, there is partial support for Android Browser and no current support for iOS Chrome or Safari, Chrome for Android or Opera Mini. There are brighter days ahead for mobile support.

More information on support visit caniuse.com

Please have in mind part of the Notifications API Specification is currently in “Recommendation” or “Living Standard” state. This means additional features may or may not become available in the foreseeable future. Some of these features include Sound and device Vibration.

ng2-notifications has these features implemented already for when the spec is ready and these features are supported by the browsers.

Want to contribute to the Notification API Standard? Submit your proposals here.

In Closing

Hopefully you’ll find this Angular 2 library useful. The Web has a long way to go, but brick by brick we’ll get to a point where building Applications successfully is more the rule rather than the exception.

What other native browser APIs could be simplified with Angular 2?