How to Add Auth to Your PWA with Okta and Stencil

This article was originally published on OKTA Blog. Thank you for supporting the partners who make SitePoint possible.
Progressive Web Applications (PWAs) are the newest technology on the web dev block, and they’ve arrived just in time to solve a growing problem. Many companies are struggling to keep isolated development teams across their organization up-to-date when new features are released. Some companies are even trying to decide if it’s worth the cost to develop both a web app and a mobile application. Not surprisingly, it’s a headache most companies are looking to avoid. PWAs can give companies a lot of the features they need from a mobile app without the need to manage multiple teams and codebases.
A PWA performs spectacularly when on a fast connection, and still performs well when offline or on Wi-Fi that’s not really fast enough to be called Wi-Fi (sometimes called “Lie-Fi”). It does so via caching and a JavaScript “Service Worker” that intercepts server calls and tries to serve the data from cache first, then when the server finally responds, it will replace the cached data with possibly “fresher” data from the server.
Recently, the Ionic team released a new project called Stencil. Stencil is a compiler that generates standards-compliant web components. Unlike most JavaScript frameworks, it doesn’t deliver a “framework” of code to the browser. It simply takes the code you write and uses its compiler to create vanilla components. You can also use Stencil’s compiler with your favorite framework. The Stencil starter project is the easiest way to get started with Stencil and produces a base application that scores nearly a 100% score on Lighthouse’s progressive web app scorecard.
To get started building a PWA using Stencil, clone the starter application and detach it from the GitHub remote.
WARNING: Stencil is not at a 1.0 release yet (as of this writing). So be aware that if you continue, you’re in early-adopter territory. If you find bugs, submit an issue.
Set Up the Starter Application
git clone https://github.com/ionic-team/stencil-starter.git first-stencil
cd first-stencil
git remote rm origin

Then, install all the dependencies that your new Stencil app will need.
npm install

You may see a couple of warnings from node-pre-gyp around fsevents. There’s nothing to see here. This is just to get around a nasty little npm bug.
Next, add the Okta Auth SDK (via CDN) to the bottom of the index.html page, right before the closing tag.
<script src=”https://ok1static.oktacdn.com/assets/js/sdk/okta-auth-js/1.8.0/okta-auth-js.min.js" type="text/javascript"></script>

While there is an npm package for Okta’s Auth SDK, Stencil has a hard time compiling it. Overall it works better for now if you just use the CDN to include it.
If you’re like me, the next thing you’ll want to do is run npm start and check the site with Lighthouse. If you do, you’ll notice that the score is kind of low. In particular, it doesn’t register a service worker or return a 200 when offline. That’s because it’s a development build, and generally, you don’t want the service worker intercepting server calls and returning cached data in development.
To ensure an accurate depiction of the kind of PWA you get out of the box with Stencil, make sure to run a production build using npm run build. Once you do, you’ll see a www folder and inside that folder, you’ll see a sw.js file. That’s your service worker!
Set Up Your Okta Application
If you haven’t already done so, create a free-forever developer account.
Once you’ve registered, click on Applications in the top menu. Then click Add Application.

You will then be taken to the application creation wizard. Choose Single-Page App and click Next at the bottom.

On the next screen, you’ll see the default settings provided by the single-page application template. Change the name of the application to something more descriptive, like “Stencil SPA”. Also, change the base URIs and the login redirect URIs settings to use port 3333 because that’s where your application will be running. The rest of the default settings are fine.

Click Done at the bottom.
Select your newly created application from the listing, and click on the General tab to view the general settings.

At the bottom, you’ll see a Client ID setting (yours won’t be blurred out, obviously). Copy this to use in your Stencil application. You will also need your Okta organization URL, which you can find at the top right of the dashboard page. It will probably look something like “https://dev-XXXXXX.oktapreview.com”.
Add the Authentication Component
In the components folder, add a new folder called app-auth. This is where your login page component will go. You can call it whatever you want, I’m just following the naming conventions set out by the starter app here. I’d definitely recommend deciding on a naming convention early and sticking with it.
Inside the newly created app-auth folder create two files: app-auth.css and app-auth.tsx. Start by creating the shell of the app-auth.tsx file.
import { Component } from ‘@stencil/core’;

@Component({
tag: ‘app-auth’,
styleUrl: ‘app-auth.css’
})
export class AppAuth {
render() {
return <div>Hello</div>;
}
}

If you are like I was, you might be thinking, “What kind of Frankenstein framework is this?”
You’ll notice the @Component decorator over the AppAuth class declaration like Angular, and then a render() method at the bottom like React. To me, that’s the beauty of Stencil. It takes some of the best parts of both popular frameworks and uses them to compile reusable components!
Add a Login Form
Next, you’ll add the JSX (that’s right, I said it) to the new component. Change the render() method to:
render() {
return (
<form class="app-auth">
<div class="form-item">
<label>
Username:
<input type="text" name="username" autocomplete="username" />
</label>
</div>
<div class="form-item">
<label>
Password:
<input
type="password"
name="password"
autocomplete="current-password"
/>
</label>
</div>
<div class="form-actions">
<button type="button" onClick={() => this.login()}>
Login
</button>
</div>
</form>
);
}

This is just a regular JSX form, but the login button’s onClick event is currently wired to function that doesn’t exist.
Add the Login Method’s Dependencies
Before you create that function, you’ll need to set up the OktaAuth JavaScript object to call the Okta API for authentication. You’ll add the object to the component’s state, so right below the class declaration, add the following line:
@State() authClient: any;

You will also have to import the @State() decorator. This is is used for values related to the internal state of the component. In the first import statement add State to the deconstruction list.
import { Component, State } from ‘@stencil/core’

You’ll also need to get the username and password values from the form itself, so add an @Element() to the code right below that @State() like you just created, so it read like this:
@State() authClient: any;
@Element() host: HTMLElement;

Then also add the @Element() decorator to the import so it reads:
import { Component, State, Element } from ‘@stencil/core’;

One last thing that the login() function will need is access to the router, so you can redirect the user to their profile page if their authentication is successful. You’ll need a class property, so add it right below the @Element.
@State() authClient: any;
@Element() host: HTMLElement;
@Prop() history: RouterHistory;

To import it, add the @Prop() decorator to the main import and then import the RouterHistory from @stencil/router right below the core import statement. The @Prop decorator is used to define properties that can be passed in to your component. In this case, it’s not a passed in value, but it could be if need be. Your final import section should read:
import { Component, Prop, State, Element, Listen } from ‘@stencil/core’;
import { RouterHistory } from ‘@stencil/router’;

Finally, to use the OktaAuth JavaScript library you brought in from the CDN, add a declaration for it right below the import statements.
declare const OktaAuth: any;

Add the Login Method
Now you included everything you’ll need to get the login function to authenticate users with your Okta organization. First, set up the OktaAuth object in the constructor of the AppAuth class. Right below the property for the RouterHistory object, add:
constructor() {
this.authClient = new OktaAuth({
clientId: ‘{yourClientId}’,
url: ‘https://{yourOktaDomain}.com’,
issuer: ‘default’
});
}

You can get your Client ID from that general settings page of your Okta application.
The post How to Add Auth to Your PWA with Okta and Stencil appeared first on SitePoint.

Link: https://www.sitepoint.com/how-to-add-auth-to-your-pwa-with-okta-and-stencil/

Interactive Data Visualization with Modern JavaScript and D3

In this article, I want to take you through an example project that I built recently — a totally original type of visualization using the D3 library, which showcases how each of these components add up to make D3 a great library to learn.
D3 stands for Data Driven Documents. It’s a JavaScript library that can be used to make all sorts of wonderful data visualizations and charts.
If you’ve ever seen any of the fabulous interactive stories from the New York Times, you’ll already have seen D3 in action. You can also see some cool examples of great projects that have been built with D3 here.
The learning curve is pretty steep for getting started with the library, since D3 has a few special quirks that you probably won’t have seen before. However, if you can get past the first phase of learning enough D3 to be dangerous, then you’ll soon be able to build some really cool stuff for yourself.
There are three main factors that really make D3 stand out from any other libraries out there:

Flexibility. D3 lets you take any kind of data, and directly associate it with shapes in the browser window. This data can be absolutely anything, allowing for a huge array of interesting use cases to create completely original visualizations.
Elegance. It’s easy to add interactive elements with smooth transitions between updates. The library is written beautifully, and once you get the hang of the syntax, it’s easy to keep your code clean and tidy.
Community. There’s a vast ecosystem of fantastic developers using D3 already, who readily share their code online. You can use sites like bl.ocks.org and blockbuilder.org to quickly find pre-written code by others, and copy these snippets directly into your own projects.

The Project
As an economics major in college, I had always been interested in income inequality. I took a few classes on the subject, and it struck me as something that wasn’t fully understood to the degree that it should be.
I started exploring income inequality using Google’s Public Data Explorer …

When you adjust for inflation, household income has stayed pretty much constant for the bottom 40% of society, although per-worker productivity has been skyrocketing. It’s only really been the top 20% that have reaped more of the benefits (and within that bracket, the difference is even more shocking if you look at the top 5%).
Here was a message that I wanted to get across in a convincing way, which provided a perfect opportunity to use some D3.js, so I started sketching up a few ideas.
Sketching
Because we’re working with D3, I could more or less just start sketching out absolutely anything that I could think of. Making a simple line graph, bar chart, or bubble chart would have been easy enough, but I wanted to make something different.
I find that the most common analogy that people tended to use as a counterargument to concerns about inequality is that “if the pie gets bigger, then there’s more to go around”. The intuition is that, if the total share of GDP manages to increase by a large extent, then even if some people are getting a thinner slice of pie, then they’ll still be better off. However, as we can see, it’s totally possible for the pie to get bigger and for people to be getting less of it overall.
My first idea for visualizing this data looked something like this:

The idea would be that we’d have this pulsating pie chart, with each slice representing a fifth of the US income distribution. The area of each pie slice would relate to how much income that segment of the population is taking in, and the total area of the chart would represent its total GDP.
However, I soon came across a bit of a problem. It turns out that the human brain is exceptionally poor at distinguishing between the size of different areas. When I mapped this out more concretely, the message wasn’t anywhere near as obvious as it should have been:

Here, it actually looks like the poorest Americans are getting richer over time, which confirms what seems to be intuitively true. I thought about this problem some more, and my solution involved keeping the angle of each arc constant, with the radius of each arc changing dynamically.

Here’s how this ended up looking in practice:

I want to point out that this image still tends to understate the effect here. The effect would have been more obvious if we used a simple bar chart:

However, I was committed to making a unique visualization, and I wanted to hammer home this message that the pie can get bigger, whilst a share of it can get smaller. Now that I had my idea, it was time to build it with D3.
Borrowing Code
So, now that I know what I’m going to build, it’s time to get into the real meat of this project, and start writing some code.
You might think that I’d start by writing my first few lines of code from scratch, but you’d be wrong. This is D3, and since we’re working with D3, we can always find some pre-written code from the community to start us off.
We’re creating something completely new, but it has a lot in common with a regular pie chart, so I took a quick look on bl.ocks.org, and I decided to go with this classic implementation by Mike Bostock, one of the creators of D3. This file has probably been copied thousands of times already, and the guy who wrote it is a real wizard with JavaScript, so we can be sure that we’re starting with a nice block of code already.
This file is written in D3 V3, which is now two versions out of date, since version 5 was finally released last month. A big change in D3 V4 was that the library switched to using a flat namespace, so that scale functions like d3.scale.ordinal() are written like d3.scaleOrdinal() instead. In version 5, the biggest change was that data loading functions are now structured as Promises, which makes it easier to handle multiple datasets at once.
To avoid confusion, I’ve already gone through the trouble of creating an updated V5 version of this code, which I’ve saved on blockbuilder.org. I’ve also converted the syntax to fit with ES6 conventions, such as switching ES5 anonymous functions to arrow functions.
Here’s what we’re starting off with already:

I then copied these files into my working directory, and made sure that I could replicate everything on my own machine. If you want to follow along with this tutorial yourself, then you can clone this project from our GitHub repo. You can start with the code in the file starter.html. Please note that you will need a server (such as this one) to run this code, as under the hood it relies on the Fetch API to retrieve the data.
Let me give you a quick rundown of how this code is working.
The post Interactive Data Visualization with Modern JavaScript and D3 appeared first on SitePoint.

Link: https://www.sitepoint.com/interactive-data-visualization-javascript-d3/

Introducing Axios, a Popular, Promise-based HTTP Client

Axios is a popular, promise-based HTTP client that sports an easy-to-use API and can be used in both the browser and Node.js.
Making HTTP requests to fetch or save data is one of the most common tasks a client-side JavaScript application will need to do. Third-party libraries — especially jQuery — have long been a popular way to interact with the more verbose browser APIs, and abstract away any cross-browser differences.
As people move away from jQuery in favor of improved native DOM APIs, or front-end UI libraries like React and Vue.js, including it purely for its $.ajax functionality makes less sense.
Let’s take a look at how to get started using Axios in your code, and see some of the features that contribute to its popularity among JavaScript developers.
Axios vs Fetch
As you’re probably aware, modern browsers ship with the newer Fetch API built in, so why not just use that? There are several differences between the two that many feel gives Axios the edge.
One such difference is in how the two libraries treat HTTP error codes. When using Fetch, if the server returns a 4xx or 5xx series error, your catch() callback won’t be triggered and it is down to the developer to check the response status code to determine if the request was successful. Axios, on the other hand, will reject the request promise if one of these status codes is returned.
Another small difference, which often trips up developers new to the API, is that Fetch doesn’t automatically send cookies back to the server when making a request. It’s necessary to explicitly pass an option for them to be included. Axios has your back here.
One difference that may end up being a show-stopper for some is progress updates on uploads/downloads. As Axios is built on top of the older XHR API, you’re able to register callback functions for onUploadProgress and onDownloadProgress to display the percentage complete in your app’s UI. Currently, Fetch has no support for doing this.
Lastly, Axios can be used in both the browser and Node.js. This facilitates sharing JavaScript code between the browser and the back end or doing server-side rendering of your front-end apps.
Note: there are versions of the Fetch API available for Node but, in my opinion, the other features Axios provides give it the edge.
Installing
As you might expect, the most common way to install Axios is via the npm package manager:
npm i axios

and include it in your code where needed:
// ES2015 style import
import axios from ‘axios’;

// Node.js style require
const axios = require(‘axios’);

If you’re not using some kind of module bundler (e.g. webpack), then you can always pull in the library from a CDN in the traditional way: