We use cookies and other tracking technologies to improve your browsing experience on our site, analyze site traffic, and understand where our audience is coming from. To find out more, please read our privacy policy.

By choosing 'I Accept', you consent to our use of cookies and other tracking technologies.

We use cookies and other tracking technologies to improve your browsing experience on our site, analyze site traffic, and understand where our audience is coming from. To find out more, please read our privacy policy.

By choosing 'I Accept', you consent to our use of cookies and other tracking technologies. Less

We use cookies and other tracking technologies... More

Login or register
to publish this job!

Login or register
to save this job!

Login or register
to save interesting jobs!

Login or register
to get access to all your job applications!

Login or register to start contributing with an article!

Login or register
to see more jobs from this company!

Login or register
to boost this post!

Show some love to the author of this blog by giving their post some rocket fuel 🚀.

Login or register to search for your ideal job!

Login or register to start working on this issue!

Login or register
to save articles!

Login to see the application

Engineers who find a new job through WorksHub average a 15% increase in salary 🚀

You will be redirected back to this page right after signin

Blog hero image

Displaying Notifications in ReScript

Eleanor Holley 15 March, 2021 | 4 min read

This article will serve to document and demonstrate the rescript-notifications npm package, a complete set of bindings for the JavaScript-compiling ReScript language (formerly BuckleScript/ReasonML). At the close of this article, the reader should be able to enable and display notifications in an entirely type safe and functional way.

Be advised that there are some limitations to web notifications, and I encourage the reader to review the JavaScript Notifications API documentation. TL;DR: Notifications require an HTTPS connection, and they are widely but not universally supported.

How to use this article

This article is meant to be both a tutorial and a demo. While I've included the code snippets I think are important, I also want to give a tour of the source so that the reader can browse it in context.

  • NotificationsDemo.res is the ReScript source for the scripts on this page. You can read the whole thing in context by reading the source on GitLab
  • It compiles to NotificationsDemo.bs.js, which is referenced in a script tag at the bottom of this article.
  • For completeness, the source of this article is also available on GitLab, although there's no magic here and you may not need it.

A word from across the web

I am adapting this article for Functional Works by stripping out the demo-ness of it all.

So feel free to read how you want! But if you'd like to see the notifications, visit the live demo site on my blog.

Setting up the project

You'll need to install the rescript-notifications npm package and add it to your bsconfig.json in the usual way.

I'm also using a local clone of bs-webapi, although of course you can always just write your own bindings for DOM manipulation.

Lastly, I just want to flag that I'm using two open statements like so:

open Notifications;
open Webapi.Dom;

(I usually try to limit myself to two or three open statements per file.)

Join our newsletter
Join over 111,000 others and get access to exclusive content, job opportunities and more!

Reading and requesting Notifications permissions

The first thing to establish is notification permissions. We do this through the Notification.permission static property and the Notification.requestPermission() static method.

For example:

NotificationsDemo.res

open Notifications;
open Webapi.Dom;

window |> Window.addEventListener("load", _ => { 
    let spanPermissions: option<Dom.element> = 
        Document.querySelector("#span-permission", document); 
    let setSpanText = (span: option<Dom.element>, text: string): unit => { 
        let _ = span -> Belt.Option.map(span => Element.setInnerText(span, text)); 
    Js.log("Permission text: " |> Js.String.concat(text)); 
}; 

let _ = spanPermissions -> setSpanText(Notification.permission); 

let onBtnRequestClick = (event: Dom.event): unit => { 
    Js.log("button-request clicked."); 

    let _ = Notification.requestPermission() 
        |> Js.Promise.then_(str => { 
           spanPermissions -> setSpanText(str) 
           |> Js.Promise.resolve 
        }); 
    }; 

    let _ = Document.querySelector("#button-request", document) 
        -> Belt.Option.map(btn => { 
           btn |> Element.addEventListener("click", onBtnRequestClick); 

           Js.log("button-request event added."); 
        });
});

As you can see, this demo sets the span text to the current notification permission state and then wires up an even to the button to ask for permission and update the span accordingly. You can see the result below:

Demo omitted in cross-post

Go ahead and grant permission if you'd like–I am only using notifications for the purposes of this demo. Ordinarily, I would hide the button after permission has been granted because it only works once, but as a demo this is fine.

Constructing notifications to display them

As long as permissions are granted, notifications are displayed as soon as they're constructed.

The rescript-notifications binding includes two Notification constructors, makeWithoutOptions and makeWithOptions.

Notifications are typed with a type parameter because they can include a data object of any datatype. If you don't need it, you can always just use a throwaway object of some sort.

The options object includes a lot of properties that the calling code won't necessarily need (and isn't necessarily widely supported), so the library includes an init function for convenience.

NotificationsDemo.res continues:

let onBtnNotifyClick = (_: Dom.event): unit => { 
    Js.log("button-notify clicked."); 
    let _ = Notification.makeWithoutOptions("You have been notified."); 
}; 

let onBtnWithOptionsClick = (_: Dom.event): unit => { 
    Js.log("button-with-options clicked."); 
    let options: NotificationOptions.t<string> = {
        ...NotificationOptions.init(Js.Nullable.return("unused data.")), 
        icon: "https://webbureaucrat.gitlab.io/img/icons/192.png", 
        body: "with an icon and additional text." 
    }; 
    let _ = Notification.makeWithOptions("You have been thoroughly notified", options); 
}; 

let _ = Document.querySelector("#button-notify", document) 
    -> Belt.Option.map(btn => { 
       btn 
       |> Element.addEventListener("click", onBtnNotifyClick); 
}); 

let _ = Document.querySelector("#button-with-options", document) 
    -> Belt.Option.map(btn => { 
    btn 
    |> Element.addEventListener("click", onBtnWithOptionsClick); 
});

As you can see, the click events call the make methods, which, by ReScript convention, bind to the Notification object constructor. The notifications will appear as soon as they are constructed.

The feel free to play with the live demo below:

Demo omitted in cross-post

Happy notifying!

This has been a quick demonstration of using JavaScript notifications in a type-safe way using ReScript. I hope you have found this helpful and informative, and, as always, feel free to reach out with questions or comments.

Originally published on webbureaucrat.gitlab.io

Author's avatar
Eleanor Holley
an enthusiastic functional programmer.

Related Issues

open-editions / corpus-joyce-ulysses-tei
open-editions / corpus-joyce-ulysses-tei
  • Started
  • 0
  • 2
  • Intermediate
  • HTML
open-editions / corpus-joyce-ulysses-tei
open-editions / corpus-joyce-ulysses-tei
  • Started
  • 0
  • 2
  • Intermediate
  • HTML
open-editions / corpus-joyce-ulysses-tei
open-editions / corpus-joyce-ulysses-tei
  • Open
  • 0
  • 0
  • Intermediate
  • HTML
open-editions / corpus-joyce-ulysses-tei
open-editions / corpus-joyce-ulysses-tei
  • Started
  • 0
  • 1
  • Intermediate
  • HTML

Get hired!

Sign up now and apply for roles at companies that interest you.

Engineers who find a new job through WorksHub average a 15% increase in salary.

Start with GitHubStart with Stack OverflowStart with Email