Finite State Machines with React

As JavaScript applications on the web have grown more complex, so too has the complexity of dealing with state in those applications — state being the aggregate of all the data that an application needs to perform its function. Over the last several years, there has been a ton of great innovation in the realm of state management through tools like Redux, MobX, and Vuex. Something that hasn’t gotten quite as much attention, though, is state design.

What in the heck do I mean by state design?

Let’s set the scene a little bit. In the past, when building an application that needs to fetch some data from a backend service and display it to the user, I’ve designed my state to use boolean flags for various things like isLoading, isSuccess, isError, and so on down the line. As this number of boolean flags grows, though, the number of possible states that my application can have grows exponentially with it — significantly increasing the likelihood of a user encountering an unintentional or error state.

To solve this issue, I’ve spent the last several months exploring the use of finite state machines as a way to better design the state of my applications.

Finite state machines are a mathematical model of computation, initially developed in the early 1940s, that have been used for decades to build both hardware and software for a wide array of technologies.

A finite state machine can be defined as any abstract machine that exists in exactly one of a finite number of states at a given time. In more practical terms, though, a state machine is characterized by a list of states with each state defining a finite, deterministic set of states that can be transitioned to by a given action.

Due to this finite and deterministic nature, we can use state diagrams to visualize our application — before or after it’s been built.

For example, if we wanted to visualize an authentication workflow, we could have three overarching states that our application could be in for a user: logged in, logged out, or loading.

A state diagram showing an application going from logged out, to loading, to logged in.

State machines, owing to their predictability, are especially popular in applications where reliability is critical — such as aviation software, manufacturing, and even the NASA Space Launch System. They’ve been a mainstay in the game development community for decades, as well.

In this article, we’ll tackle building something that most applications on the web use: authentication. We’ll use the state diagram above to guide us.

Before we get started, though, let’s familiarize ourselves with some of the libraries and APIs we’ll be using to build this application.

React Context API

React 16.3 introduced a new, stable version of the Context API. If you’ve worked much with React in the past, you may be familiar with how data is passed from parent to child through props. When you have certain data that is needed by a variety of components, you can end up doing what’s known as prop drilling — passing data through multiple levels of the component tree to get the data to a component that needs it.

Context helps alleviate the pain of prop drilling by providing a way to share data between components without having to explicitly pass that data through the component tree, making it perfect for storing authentication data.

When we create context, we get a Provider and Consumer pair. The provider will act as the “smart,” stateful component that contains our state machine definition, and maintains a record of the current state of our application.

xstate

xstate is a JavaScript library for functional, stateless finite state machines and statecharts — it will provide us a nice, clean API for managing definitions and transitions through our states.

A stateless finite state machine library might sound a bit strange, but essentially what it means is that xstate only cares about the state and transition that you pass it — meaning it’s up to your application to keep track of its own current state.

xstate has a lot of features worth mentioning that we won’t cover much in this article (since we’ll only begin to scratch the surface on statecharts): hierarchical machines, parallel machines, history states, and guards, just to name a few.

The approach

So, now that we’ve had a little bit of an introduction to both Context and xstate, let’s talk about the approach we’ll be taking.

We’ll start by defining the context for our application, then creating a stateful <App /> component (our provider) that will contain our authentication state machine, along with information about the current user and a method for the user to logout.

To set the stage a bit, let’s take a quick look at a CodePen demo of what we’ll be building.

See the Pen Authentication state machine example by Jon Bellah (@jonbellah) on CodePen.

So, without further ado, let’s dig into some code!

Defining our context

The first thing we need to do is define our application context and set it up with some default values. Default values in context are helpful for allowing us to test components in isolation, since the default values are only used if there is no matching provider.

For our application, we’re going to set up a few defaults: authState which will be the authentication state of the current user, an object called user which will contain data about our user if they’re authenticated, then a logout() method that can be called anywhere in the app if the user is authenticated.

const Auth = React.createContext({ authState: 'login', logout: () => {}, user: {},
});

Defining our machine

When we think about how authentication behaves in an application, in its simplest form, there are three primary states: logged out, logged in, and loading. These are the three states we diagramed earlier.

Looking back at that state diagram, our machine consists of those same three states: logged out, logged in, and loading. We also have four different action types that can be fired: SUBMIT, SUCCESS, FAIL, and LOGOUT.

We can model that behavior in code like so:

const appMachine = Machine({ initial: 'loggedOut', states: { loggedOut: { onEntry: ['error'], on: { SUBMIT: 'loading', }, }, loading: { on: { SUCCESS: 'loggedIn', FAIL: 'loggedOut', }, }, loggedIn: { onEntry: ['setUser'], onExit: ['unsetUser'], on: { LOGOUT: 'loggedOut', }, }, },
});

So, we just expressed the diagram from earlier in code, but are you ready for me to let you in on a little secret? That diagram was generated from this code using David Khourshid’s xviz library — which can be used to visually explore the actual code that powers your state machines.

If you’re interested in diving deeper into complex user interfaces using finite state machines, David Khourshid has a related article here on CSS-Tricks worth checking out.

This can be an incredibly powerful tool when trying to debug problematic states in your application.

Referring back to the code above now, we define our initial application state — which we’re calling loggedOut since we’ll want to show the login screen on an initial visit.

Note that in a typical application, you’d probably want to start from the loading state and determine if the user was previously authenticated… but since we’re faking the login process, we’re starting from the logged out state.

In the states object, we define each of our states along with the corresponding actions and transitions for each of those states. Then we pass all that as an object to the Machine() function, which is imported from xstate.

Along with our loggedOut and loggedIn states, we’ve defined some actions that we want to fire when our application enters or exits those states. We’ll look at what those actions do in a bit.

This is our state machine.

To break things down one more time, let’s look at the loggedOut: { on: { SUBMIT: 'loading'} } line . This means that if our application is in the loggedOut state and we call our transition function with an action of SUBMIT, our application will always transition from the loggedOut state to the loading state. We can make that transition by calling appMachine.transition('loggedOut', 'SUBMIT').

From there, the loading state will either move the user along as an authenticated user or send them back to the login screen and display an error message.

Creating our context provider

The context provider will be the component that sits at the top level of our application and houses all the data related to an authenticated — or unauthenticated — user.

Working in the same file as our state machine definition, let’s create an <App /> component and set it up with everything we’ll need. Don’t worry, we’ll cover what each method does in just a moment.

class App extends React.Component { constructor(props) { super(props); this.state = { authState: appMachine.initialState.value, error: '', logout: e => this.logout(e), user: {}, }; } transition(event) { const nextAuthState = appMachine.transition(this.state.authState, event.type); const nextState = nextAuthState.actions.reduce( (state, action) => this.command(action, event) || state, undefined, ); this.setState({ authState: nextAuthState.value, ...nextState, }); } command(action, event) { switch (action) { case 'setUser': if (event.username) { return { user: { name: event.username } }; } break; case 'unsetUser': return { user: {}, }; case 'error': if (event.error) { return { error: event.error, }; } break; default: break; } } logout(e) { e.preventDefault(); this.transition({ type: 'LOGOUT' }); } render() { return ( <Auth.Provider value={this.state}> <div className="w5"> <div className="mb2">{this.state.error}</div> {this.state.authState === 'loggedIn' ? ( <Dashboard /> ) : ( <Login transition={event => this.transition(event)} /> )} </div> </Auth.Provider> ); }
}

Whew, that was a lot of code! Let’s break it down into manageable chunks by taking a look at each method of this class individually.

In the constructor(), we’re setting our component state to the initial state of our appMachine, as well as setting our logout function in state, so that it can be passed through our application context to any consumer that needs it.

In the transition() method, we’re doing a few important things. First, we’re passing our current application state and the event type or action to xstate, so we can determine our next state. Then, in nextState, we take any actions associated with that next state (which will be one of our onEntry or onExit actions) and run them through the command() method — then we take all of the results and set our new application state.

In the command() method, we have a switch statement that returns an object — depending on the action type — which we use to pass data into our application state. This way, once a user has authenticated, we can set relevant details about that user — username, email, id, etc. — into our context, making it available to any of our consumer components.

Finally, in our render() method, we’re actually defining our provider component and then passing all of our current state through the value props, which makes the state available to all of the components beneath it in the component tree. Then, depending on the state of our application, we’re rendering either the dashboard or the login form for the user.

In this case, we have a pretty flat component tree beneath our provider (Auth.Provider), but remember that context allows that value to be available to any component beneath our provider in the component tree, regardless of depth. So, for example, if we have a component nested three or four levels down and we want to display the current user name, we can just grab that out of context, rather than drilling it all the way down to that one component.

Creating context consumers

Now, let’s create some components that consume our application context. From these components, we can do all sorts of things.

We can start by building a login component for our application.

class Login extends Component { constructor(props) { super(props); this.state = { yourName: '', } this.handleInput = this.handleInput.bind(this); } handleInput(e) { this.setState({ yourName: e.target.value, }); } login(e) { e.preventDefault(); this.props.transition({ type: 'SUBMIT' }); setTimeout(() => { if (this.state.yourName) { return this.props.transition({ type: 'SUCCESS', username: this.state.yourName, }, () => { this.setState({ username: '' }); }); } return this.props.transition({ type: 'FAIL', error: 'Uh oh, you must enter your name!', }); }, 2000); } render() { return ( <Auth.Consumer> {({ authState }) => ( <form onSubmit={e => this.login(e)}> <label htmlFor="yourName"> <span>Your name</span> <input id="yourName" name="yourName" type="text" value={this.state.yourName} onChange={this.handleInput} /> </label> <input type="submit" value={authState === 'loading' ? 'Logging in...' : 'Login' } disabled={authState === 'loading' ? true : false} /> </form> )} </Auth.Consumer> ); }
}

Oh my! That was another big chunk of code, so let’s walk through each method again.

In the constructor(), we’re declaring our default state and binding the handleInput() method so that it references the proper this internally.

In handleInput(), we’re taking the value of our form field from our render() method and setting that value in state — this is referred to as a controlled form.

The login() method is where you would normally place your authentication logic. In the case of this app, we’re just faking a delay with setTimeout() and either authenticating the user — if they’ve provided a name — or returning an error if the field was left empty. Note that the transition() function that it calls is actually the one we defined in our <App /> component, which has been passed down via props.

Finally, our render() method displays our login form, but notice that the <Login /> component is also a context consumer. We’re using the authState context to determine whether or not to show our login button in a disabled, loading state.

Using context from deep in the component tree

Now that we’ve handled the creation of our state machine and a way for users to login to our application, we can now rely on having information about that user within any component nested under our <Dashboard /> component — since it will only ever be rendered if the user is logged in.

So let’s create a stateless component that grabs the username of the current authenticated user and displays a welcome message. Since we’re passing the logout() method to all of our consumers, we can also give the user the option of logging out from anywhere in the component tree.

const Dashboard = () => ( <Auth.Consumer> {({ user, logout }) => ( <div> <div>Hello {user.name}</div> <button onClick={e => logout(e)}> Logout </button> </div> )} </Auth.Consumer>
);

Building larger applications with statecharts

Using finite state machines with React doesn’t have to be limited to authentication, nor does it have to be limited to the context API.

Using statecharts, you can have hierarchical machines and/or parallel machines — meaning individual React components can have their own internal state machine, but still be connected to the overall state of your application.

In this article, we’ve primarily focused on using xstate directly with the native Context API; in larger applications, I highly recommend looking at react-automata, which provides a thin layer of abstraction over the top of xstate. react-automata has the added benefit of being able to automagically generate Jest tests for your components.

State machines and state management tools are not mutually exclusive

It’s easy to get confused by thinking you must either use, say, xstate or Redux; but it’s important to note that state machines are more of an implementation concept, concerned with how you design your state — not necessarily how you manage it.

In fact, state machines can be used with just about any un-opinionated state management tool. I encourage you to explore various approaches to determine what works best for you, your team, and your application(s).

In conclusion

These concepts can be extended to the real world without having to refactor your entire application. State machines are an excellent refactor target — meaning, next time you’re working on a component that is littered with boolean flags like isFetching and isError, consider refactoring that component to use a state machine.

As a front-end developer, I’ve found that I’m often fixing one of two categories of bugs: display-related issues or unexpected application states.

State machines make the second category virtually disappear.

If you’re interested in diving deeper into state machines, I’ve spent the last several months working on a course on finite state machines — if you sign up for the email list, you’ll receive a discount code when the course launches in August.

The post Finite State Machines with React appeared first on CSS-Tricks.

How to make a modern dashboard with NVD3.js

NVD3.js is a JavaScript visualization library that is free to use and open source. It’s derived from the well-known d3.js visualization library. When used the right way, this library can be extremely powerful for everyday tasks and even business operations.

For example, an online dashboard. We can use NVD3.js to compile data into a centralized space that visualizes the information in neat charts and graphs. That’s what we’re going to look at in this post.

Making a dashboard with NVD3.js for the first time is daunting, but after this tutorial, you should have the required knowledge to get your hands dirty and start building something awesome. Personally, I have a passion for visualizations on the web. They are both beautiful and meaningful at the same time.

Real-world use case: A data dashboard

Dashboards can be used for pretty much anything. As long as you’ve got data to analyze, you’re good to go, whether that be some sales data or the average weather for the last 20 years. Let’s build something like this:

See the Pen Dashboard NVD3.JS by Danny Englishby (@DanEnglishby) on CodePen.

Setting up the environment

To setup an NVD3 chart, we require three things:

  1. The NVD3 JavaScript library
  2. The NVD3 CSS library
  3. The D3.js library (a dependency for NVD3)

All of these are available through Cloudflare’s CDN network. Here’s an HTML template with all those resources ready to go:

<!doctype html>
<html lang="en">
<head> <meta charset="utf-8"> <title>Making a Dashboard</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.6/nv.d3.css">
</head>
<body> </body>
</html>

Data sources

For this tutorial, I thought using some raw, factual data that’s already been formatted into JSON would be easiest. I’m using two sources of information: one about global average temperatures over time and the other reporting world population statistics. I’ve already formatted the data into JSON, so it’s ready to copy and paste!

Creating a line chart

Let’s go ahead and create a line chart with some global temperature data. The raw data I’ve put together in JSON represents the last twenty years of temperature changes compared to the global average.

First, we’ll add a placeholder element for the chart to attach to when the JavaScript is executed.

<div id="averageDegreesLineChart" class='with-3d-shadow with-transitions averageDegreesLineChart'> <svg></svg>
</div>

Then add the following JSON in some script tags before the </body> tag:

var temperatureIndexJSON = [ { key: "Temp +- Avg.", values: [{ "x": 1998, "y": 0.45 }, { "x": 1999, "y": 0.48 }, { "x": 2000, "y": 0.5 }, { "x": 2001, "y": 0.52 }, { "x": 2002, "y": 0.55 }, { "x": 2003, "y": 0.58 }, { "x": 2004, "y": 0.6 }, { "x": 2005, "y": 0.61 }, { "x": 2006, "y": 0.61 }, { "x": 2007, "y": 0.61 }, { "x": 2008, "y": 0.62 }, { "x": 2009, "y": 0.62 }, { "x": 2010, "y": 0.62 }, { "x": 2011, "y": 0.63 }, { "x": 2012, "y": 0.67 }, { "x": 2013, "y": 0.71 }, { "x": 2014, "y": 0.77 }, { "x": 2015, "y": 0.83 }, { "x": 2016, "y": 0.89 }, { "x": 2017, "y": 0.95 }] }
];

The x value is the year and they value is the temperature in Celsius degrees.

The last piece to the puzzle is the most important function that creates the chart. The function named nv.addGraph() is the main function used throughout NVD3 and, within it, you initialize the chart object. In this example, we are using the lineChart object which can have methods chained to it, depending on what the visual requirements may be.

Check out the JavaScript comments to see the which each line does.

nv.addGraph(function () { var chart = nv.models.lineChart() // Initialise the lineChart object. .useInteractiveGuideline(true); // Turn on interactive guideline (tooltips) chart.xAxis .axisLabel('TimeStamp (Year)'); // Set the label of the xAxis (Vertical)
chart.yAxis .axisLabel('Degrees (c)') // Set the label of the xAxis (Horizontal) .tickFormat(d3.format('.02f')); // Rounded Numbers Format.
d3.select('#averageDegreesLineChart svg') // Select the ID of the html element we defined earlier. .datum(temperatureIndexJSON) // Pass in the JSON .transition().duration(500) // Set transition speed .call(chart); // Call & Render the chart nv.utils.windowResize(chart.update); // Intitiate listener for window resize so the chart responds and changes width. return;
});

See the Pen Line Chart NVD3.JS by Danny Englishby (@DanEnglishby) on CodePen.

Creating two bar charts for the price of one

You will love the minimal effort of these next two charts. The power of NVD3.js enables switching between chart types. You can either have the toggle active so users can switch between a standard bar chart or a stacked bar chart. Or you can force the chart type and make it unchangeable.

The following examples show exactly how to do it.

Stacked multi-bar chart

You know those bar charts that stack two values together in the same bar? That’s what we’re doing here.

<div id="worldPopulationMultiBar" class="with-3d-shadow with-transitions worldPopulationMultiBar"> <svg></svg>
</div>
var populationBySexAndCountryJSON =[{"key":"Male","color":"#d62728","values":[{"label":"China","value":717723466.166},{"label":"India","value":647356171.132},{"label":"United States of America","value":157464952.272},{"label":"Indonesia","value":125682412.393},{"label":"Brazil","value":98578067.1},{"label":"Pakistan","value":93621293.316},{"label":"Nigeria","value":88370210.605},{"label":"Bangladesh","value":79237050.772},{"label":"Russian Federation","value":65846330.629},{"label":"Japan","value":61918921.999}]},{"key":"Female","color":"#1f77b4","values":[{"label":"China","value":667843070.834},{"label":"India","value":604783424.868},{"label":"United States of America","value":162585763.728},{"label":"Indonesia","value":124183218.607},{"label":"Brazil","value":101783857.9},{"label":"Pakistan","value":88521300.684},{"label":"Nigeria","value":85245134.395},{"label":"Bangladesh","value":77357911.228},{"label":"Russian Federation","value":76987358.371},{"label":"Japan","value":65224655.001}]}]; nv.addGraph(function ()
{ var chart = nv.models.multiBarChart() .x(function (d) { return d.label; // Configure x axis to use the "label" within the json. }) .y(function (d) { return d.value; // Configure y axis to use the "value" within the json. }).margin({top: 30, right: 20, bottom: 50, left: 85}) // Add some CSS Margin to the chart. .showControls(false) // Turn of switchable control .stacked(true); // Force stacked mode. chart.xAxis.axisLabel('Countries'); // add label to the horizontal axis chart.yAxis.tickFormat(d3.format('0f')); // Round the yAxis values d3.select('#worldPopulationMultiBar svg') // Select the html element by ID .datum(populationBySexAndCountryJSON) // Pass in the data .transition().duration(500) // Set transition speed .call(chart); // Call & Render chart nv.utils.windowResize(chart.update); // Intitiate listener for window resize so the chart responds and changes width. return;
});

The two important settings in the JavaScript here are the .showControls and .stacked booleans. They both do what they say on the tin: force the graph to a stacked bar chart and don’t allow switching of the chart type. You will see what I mean by switching soon.

See the Pen Multi StackedBar NVD3.JS by Danny Englishby (@DanEnglishby) on CodePen.

Standard multi-bar chart

Now, let’s do something a little more traditional and compare values side-by-side instead of stacking them in the same bar.

This uses pretty much the same code as the stacked examples, but we can change the .stacked boolean value to false. This will, of course, make the stacked bar chart a normal bar chart.

<div id="worldPopulationMultiBar" class="with-3d-shadow with-transitions worldPopulationMultiBar"> <svg></svg>
</div>
var populationBySexAndCountryJSON = [{"key":"Male","color":"#d62728","values":[{"label":"China","value":717723466.166},{"label":"India","value":647356171.132},{"label":"United States of America","value":157464952.272},{"label":"Indonesia","value":125682412.393},{"label":"Brazil","value":98578067.1},{"label":"Pakistan","value":93621293.316},{"label":"Nigeria","value":88370210.605},{"label":"Bangladesh","value":79237050.772},{"label":"Russian Federation","value":65846330.629},{"label":"Japan","value":61918921.999}]},{"key":"Female","color":"#1f77b4","values":[{"label":"China","value":667843070.834},{"label":"India","value":604783424.868},{"label":"United States of America","value":162585763.728},{"label":"Indonesia","value":124183218.607},{"label":"Brazil","value":101783857.9},{"label":"Pakistan","value":88521300.684},{"label":"Nigeria","value":85245134.395},{"label":"Bangladesh","value":77357911.228},{"label":"Russian Federation","value":76987358.371},{"label":"Japan","value":65224655.001}]}]; nv.addGraph(function () { var chart = nv.models.multiBarChart() .x(function (d) { return d.label; // Configure x axis to use the "label" within the json. }) .y(function (d) { return d.value; // Configure y axis to use the "value" within the json. }).margin({top: 30, right: 20, bottom: 50, left: 85}) // Add some CSS Margin to the chart. .showControls(false) // Turn of switchable control .stacked(false); // ***Force normal bar mode.*** chart.xAxis.axisLabel('Countries'); // add label to the horizontal axis chart.yAxis.tickFormat(d3.format('0f')); // Round the yAxis values d3.select('#worldPopulationMultiBar svg') // Select the html element by ID .datum(populationBySexAndCountryJSON) // Pass in the data .transition().duration(500) // Set transition speed .call(chart); // Call & Render chart nv.utils.windowResize(chart.update); // Intitiate listener for window resize so the chart responds and changes width. return;
});

The one change to the settings presents us with a brand-new looking chart.

See the Pen Multi Bar NVD3.JS by Danny Englishby (@DanEnglishby) on CodePen.

Using one code set with minimal changes, you just created two epic charts for the price of one. Kudos for you!

There is one last setting, of course, if you want the functionality of switching charts. Change the .showControls to true and remove the .stacked option. You will notice some controls at the top of the chart. Clicking them will toggle the view between a stacked and standard chart.

See the Pen Multi Bar Switchable NVD3.JS by Danny Englishby (@DanEnglishby) on CodePen.

Making a dashboard

There’s nothing I love looking at more in the world of web development than dashboards. They never get old and are super good looking. By using the charting techniques we’ve already covered, we can make our own responsive dashboard on a single webpage.

If you remember within the JavaScript snippets earlier, there was a function set with a listener against each chart: nv.utils.windowResize(chart.update);

This magical function, resizes the chart for you as if it was set to width: 100% in CSS. But it doesn’t just shrink, but also moves and restructures the graph according to the size of the screen. It’s pretty awesome! All we need to worry about it are the heights. We can set this up by applying flexbox to the classes assigned to chart elements.

Let’s bundle everything we have so far into one dashboard by wrapping each chart element in a flexbox container. Apply a small amount of CSS for the flexing and height, and finally, compile all the scripts into one (or, you can keep them separate in your own project).

See the Pen Dashboard NVD3.JS by Danny Englishby (@DanEnglishby) on CodePen.

Summary

This tutorial will hopefully give you the knowledge to get started with building data visualizations and, ultimately, add them into a production dashboard. Even if you only want to play with these concepts, I’m sure your mind will start running with ideas for how to transform different types of data into stunning visuals.

The post How to make a modern dashboard with NVD3.js appeared first on CSS-Tricks.

​The State of Headless CMS Market

(This is a sponsored post.)

In March and April 2018, Kentico conducted the first global report about the state of headless CMS market. We surveyed 986 CMS practitioners in 85 countries about their opinions, adoption, and plans for using headless CMS. The survey contains valuable industry insights into topics such headless CMS awareness, preferred headless CMS models, current and future uptake of the headless CMS approach, and much more, from leading industry players.

Download your complimentary copy of the full report now.

Direct Link to Article — Permalink

The post ​The State of Headless CMS Market appeared first on CSS-Tricks.

What bit of advice would you share with someone new to your field?

The most FA of all the FAQs.

Here’s Laura Kalbag:

Find what you love. Don’t worry about needing to learn every language, technique or tool. Start with what interests you, and carve your own niche. And then use your powers for good!

And my own:

Buy a domain name. Figure out how to put an HTML file up there. Isn’t that a powerful feeling? Now you’ve got table stakes. Build something.

Definitely, go read other A Book Apart author answers because they are all great. My other favorite is just three words.

Direct Link to Article — Permalink

The post What bit of advice would you share with someone new to your field? appeared first on CSS-Tricks.

Automate Your Workflow with Node

You know those tedious tasks you have to do at work: Updating configuration files, copying and pasting files, updating Jira tickets.

Time adds up after a while. This was very much the case when I worked for an online games company back in 2016. The job could be very rewarding at times when I had to build configurable templates for games, but about 70% of my time was spent on making copies of those templates and deploying re-skinned implementations.

What is a reskin?

The definition of a reskin at the company was using the same game mechanics, screens and positioning of elements, but changing the visual aesthetics such as color and assets. So in the context of a simple game like ‘Rock Paper Scissors,’ we would create a template with basic assets like below.

But when we create a reskin of this, we would use different assets and the game would still work. If you look at games like Candy Crush or Angry Birds, you’ll find that they have many varieties of the same game. Usually Halloween, Christmas or Easter releases. From a business perspective it makes perfect sense.

Now… back to our implementation. Each of our games would share the same bundled JavaScript file, and load in a JSON file that had different content and asset paths. The result?

The good thing about extracting configurable values into a JSON file is that you can modify the properties without having to recompile/build the game again. Using Node.js and the original breakout game created by Mozilla, we will make a very simple example of how you can create a configurable template, and make releases from it by using the command line.

Our game

This is the game we’ll be making. Reskins of MDN Breakout, based on the existing source code.

Gameplay screen from the game MDN Breakout where you can use your paddle to bounce the ball and destroy the brick field, with keeping the score and lives.

The primary color will paint the text, paddle, ball and blocks, and the secondary color will paint the background. We will proceed with an example of a dark blue background and a light sky blue for the foreground objects.

Prerequisites

You will need to ensure the following:

  • You have Git installed – https://git-scm.com/downloads
  • You have Node installed – https://nodejs.org/en/download
  • You have a GitHub account – https://github.com
  • You have cloned the repository locally – https://github.com/smks/nobot-examples.git
  • You have ran npm install in the root of the nobot-examples project.
  • Finally, you run the local server by running npm run gameServe in the root of the project via a terminal.

We have tweaked the original Firefox implementation so that we first read in the JSON file and then build the game using HTML Canvas. The game will read in a primary color, and a secondary color from our game.json file.

{ "primaryColor": "#fff", "secondaryColor": "#000"
}

We will be using example 20 from the book Automating with Node.js. The source code can be found here.

Open up a new command line (CMD for Windows, Terminal for Unix-like Operating systems) and change into the following directory once you have cloned the repository locally.

$ cd nobot-examples/examples/020

Remember the game server should be running in a separate terminal.

Our JSON file sits beside an index.html file inside a directory called template. This is the directory that we will copy from whenever we want to do a new release/copy.

<!DOCTYPE html>
<html>
<head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Paddle Game</title> <style> * { padding: 0; margin: 0; } canvas { background: #eee; display: block; margin: 0 auto; } </style>
</head>
<body> <canvas id="game" width="480" height="320"></canvas> <script type="text/javascript" src="../../core/game-1.0.0.js"></script>
</body>
</html>

You see above that every game we release will point to the same core bundle JavaScript file. Let’s have a look at our JavaScript implementation under the core directory.

Don’t look too much into the mechanics of how the game works, more so how we inject values into the game to make it configurable.

(function boot(document) { function runGame(config) { const canvas = document.getElementById('game'); canvas.style.backgroundColor = config.secondaryColor; // rest of game source code gets executed... hidden for brevity // source can be found here: https://git.io/vh1Te } function loadConfig() { fetch('game.json') .then(response => response.json()) .then(runGame); } document.addEventListener('DOMContentLoaded', () => { loadConfig(); });
}(document));

The source code is using ES6 features and may not work in older browsers. Run through Babel if this is a problem for you.

You can see that we are waiting for the DOM content to load, and then we are invoking a method called loadConfig. This is going to make an AJAX request to game.json, fetch our JSON values, and once it has retrieved them, it will initiate the game and assign the styles in the source code.

Here is an example of the configuration setting the background color.

const canvas = document.getElementById('game');
canvas.style.backgroundColor = config.secondaryColor; // overriding color here

So, now that we have a template that can be configurable, we can move on to creating a Node.js script that will allow the user to either pass the name of the game and the colors as options to our new script, or will prompt the user for: the name of the game, the primary color, and then the secondary color. Our script will enforce validation to make sure that both colors are in the format of a hex code (e.g. #101b6b).

When we want to create a new game reskin, we should be able to run this command to generate it:

$ node new-reskin.js --gameName='blue-reskin' --gamePrimaryColor='#76cad8' --gameSecondaryColor='#10496b'

The command above will build the game immediately, because it has the three values it needs to release the reskin.

We will create this script new-reskin.js, and this file carries out the following steps:

  1. It will read in the options passed in the command line and store them as variables. Options can be read in by looking in the process object (process.argv).
  2. It will validate the values making sure that the game name, and the colors are not undefined.
  3. If there are any validation issues, it will prompt the user to re-enter it correctly before proceeding.
  4. Now that it has the values, it will make a copy of the template directory and place a copy of it into the releases directory and name the new directory with the name of the game we gave it.
  5. It will then read the JSON file just recently created under the releases directory and override the values with the values we passed (the colors).
  6. At the end, it will prompt the user to see if they would like to open the game in a browser. It adds some convenience, rather than us trying to remember what the URL is.

Here is the full script. We will walk through it afterwards.

require('colors');
const argv = require('minimist')(process.argv.slice(2));
const path = require('path');
const readLineSync = require('readline-sync');
const fse = require('fs-extra');
const open = require('opn');
const GAME_JSON_FILENAME = 'game.json'; let { gameName, gamePrimaryColor, gameSecondaryColor } = argv; if (gameName === undefined) { gameName = readLineSync.question('What is the name of the new reskin? ', { limit: input => input.trim().length > 0, limitMessage: 'The project has to have a name, try again' });
} const confirmColorInput = (color, colorType = 'primary') => { const hexColorRegex = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/; if (hexColorRegex.test(color)) { return color; } return readLineSync.question(`Enter a Hex Code for the game ${colorType} color `, { limit: hexColorRegex, limitMessage: 'Enter a valid hex code: #efefef' });
}; gamePrimaryColor = confirmColorInput(gamePrimaryColor, 'primary');
gameSecondaryColor = confirmColorInput(gameSecondaryColor, 'secondary'); console.log(`Creating a new reskin '${gameName}' with skin color: Primary: '${gamePrimaryColor}' Secondary: '${gameSecondaryColor}'`); const src = path.join(__dirname, 'template');
const destination = path.join(__dirname, 'releases', gameName);
const configurationFilePath = path.join(destination, GAME_JSON_FILENAME);
const projectToOpen = path.join('http://localhost:8080', 'releases', gameName, 'index.html'); fse.copy(src, destination) .then(() => { console.log(`Successfully created ${destination}`.green); return fse.readJson(configurationFilePath); }) .then((config) => { const newConfig = config; newConfig.primaryColor = gamePrimaryColor; newConfig.secondaryColor = gameSecondaryColor; return fse.writeJson(configurationFilePath, newConfig); }) .then(() => { console.log(`Updated configuration file ${configurationFilePath}`green); openGameIfAgreed(projectToOpen); }) .catch(console.error); const openGameIfAgreed = (fileToOpen) => { const isOpeningGame = readLineSync.keyInYN('Would you like to open the game? '); if (isOpeningGame) { open(fileToOpen); }
};

At the top of the script, we require the packages needed to carry out the process.

  • colors to be used to signify success or failure using green or red text.
  • minimist to make it easier to pass arguments to our script and to parse them optionally. Pass input without being prompted to enter.
  • path to construct paths to the template and the destination of the new game.
  • readline-sync to prompt user for information if it’s missing.
  • fs-extra so we can copy and paste our game template. An extension of the native fs module.
  • opn is a library that is cross platform and will open up our game in a browser upon completion.

The majority of the modules above would’ve been downloaded/installed when you ran npm install in the root of the nobot-examples repository. The rest are native to Node.

We check if the game name was passed as an option through the command line, and if it hasn’t been, we prompt the user for it.

// name of our JSON file. We store it as a constant
const GAME_JSON_FILENAME = 'game.json'; // Retrieved from the command line --gameName='my-game' etc.
let { gameName, gamePrimaryColor, gameSecondaryColor } = argv; // was the gameName passed?
if (gameName === undefined) { gameName = readLineSync.question('What is the name of the new reskin? ', { limit: input => input.trim().length > 0, limitMessage: 'The project has to have a name, try again' });
}

Because two of our values need to be hex codes, we create a function that can do the check for both colors: the primary and the secondary. If the color supplied by the user does not pass our validation, we prompt for the color until it does.

// Does the color passed in meet our validation requirements?
const confirmColorInput = (color, colorType = 'primary') => { const hexColorRegex = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/; if (hexColorRegex.test(color)) { return color; } return readLineSync.question(`Enter a Hex Code for the game ${colorType} color `, { limit: hexColorRegex, limitMessage: 'Enter a valid hex code: #efefef' });
};

We use the function above to obtain both the primary and secondary colors.

gamePrimaryColor = confirmColorInput(gamePrimaryColor, 'primary');
gameSecondaryColor = confirmColorInput(gameSecondaryColor, 'secondary');

In the next block of code, we are printing to standard output (console.log) to confirm the values that will be used in the process of building the game. The statements that follow are preparing the paths to the relevant files and directories.

The src will point to the template directory. The destination will point to a new directory under releases. The configuration file that will have its values updated will reside under this new game directory we are creating. And finally, to preview our new game, we construct the URL using the path to the local server we booted up earlier on.

console.log(`Creating a new reskin '${gameName}' with skin color: Primary: '${gamePrimaryColor}' Secondary: '${gameSecondaryColor}'`);
const src = path.join(__dirname, 'template');
const destination = path.join(__dirname, 'releases', gameName);
const configurationFilePath = path.join(destination, GAME_JSON_FILENAME);
const projectToOpen = path.join('http://localhost:8080', 'releases', gameName, 'index.html');

In the code following this explanation, we:

  • Copy the template files to the releases directory.
  • After this is created, we read the JSON of the original template values.
  • With the new configuration object, we override the existing primary and secondary colors provided by the user’s input.
  • We rewrite the JSON file so it has the new values.
  • When the JSON file has been updated, we ask the user if they would like to open the new game in a browser.
  • If anything went wrong, we catch the error and log it out.
fse.copy(src, destination) .then(() => { console.log(`Successfully created ${destination}`green); return fse.readJson(configurationFilePath); }) .then((config) => { const newConfig = config; newConfig.primaryColor = gamePrimaryColor; newConfig.secondaryColor = gameSecondaryColor; return fse.writeJson(configurationFilePath, newConfig); }) .then(() => { console.log(`Updated configuration file ${configurationFilePath}`green); openGameIfAgreed(projectToOpen); }) .catch(console.error);

Below is the function that gets invoked when the copying has completed. It will then prompt the user to see if they would like to open up the game in the browser. The user responds with y or n

const openGameIfAgreed = (fileToOpen) => { const isOpeningGame = readLineSync.keyInYN('Would you like to open the game? '); if (isOpeningGame) { open(fileToOpen); }
};

Let’s see it in action when we don’t pass any arguments. You can see it doesn’t break, and instead prompts the user for the values it needs.

$ node new-reskin.js
What is the name of the new reskin? blue-reskin
Enter a Hex Code for the game primary color #76cad8
Enter a Hex Code for the game secondary color #10496b
Creating a new reskin 'blue-reskin' with skin color: Primary: '#76cad8' Secondary: '#10496b'
Successfully created nobot-examples\examples\020\releases\blue-reskin
Updated configuration file nobot-examples\examples\020\releases\blue-reskin\game.json
Would you like to open the game? [y/n]: y
(opens game in browser)

My game opens on my localhost server automatically and the game commences, with the new colors. Sweet!

Oh… I’ve lost a life already. Now if you navigate to the releases directory, you will see a new directory called blue-reskin This contains the values in the JSON file we entered during the script execution.

Below are a few more releases I made by running the same command. You can imagine if you were releasing games that could configure different: images, sounds, labels, content and fonts, you would have a rich library of games based on the same mechanics.

Even better, if the stakeholders and designers had all of this information in a Jira ticket, you could integrate the Jira API into the Node script to inject these values in without the user having to provide any input. Winning!


This is one of many examples that can be found in Automating with Node.js. In this book, we will be looking at a more advanced example using “Rock Paper Scissors” as the basis of a build tool created from scratch.

  • Color Print: http://amzn.eu/aA0cSnu
  • Kindle: https://amzn.to/2JPTk7q
  • Kobo: https://www.kobo.com/gb/en/ebook/automating-with-node-js
  • Leanpub: https://leanpub.com/automatingwithnodejs

The post Automate Your Workflow with Node appeared first on CSS-Tricks.

CSS-in-JS: FTW || WTF?

I enjoyed Bruce Lawson’s talk on this holiest of wars. It’s funny and lighthearted while being well researched and fairly portraying the good arguments on both sides.

The post CSS-in-JS: FTW || WTF? appeared first on CSS-Tricks.

Render Children in React Using Fragment or Array Components

What comes to your mind when React 16 comes up? Context? Error Boundary? Those are on point. React 16 came with those goodies and much more, but In this post, we’ll be looking at the rendering power it also introduced — namely, the ability to render children using Fragments and Array Components.

These are new and really exciting concepts that came out of the React 16 release, so let’s look at them closer and get to know them.

Fragments

It used to be that React components could only return a single element. If you have ever tried to return more than one element, you know that you’ll will be greeted with this error: Syntax error: Adjacent JSX elements must be wrapped in an enclosing tag. The way out of that is to make use of a wrapper div or span element that acts as the enclosing tag.

So instead of doing this:

class Countries extends React.Component { render() { return ( <li>Canada</li> <li>Australia</li> <li>Norway</li> <li>Mexico</li> ) }
}

…you have to add either an ol or ul tag as a wrapper on those list items:

class Countries extends React.Component { render() { return ( <ul> <li>Canada</li> <li>Australia</li> <li>Norway</li> <li>Mexico</li> </ul> ) }
}

Most times, this may not be the initial design you had for the application, but you are left with no choice but to compromise on this ground.

React 16 solves this with Fragments. This new features allows you to wrap a list of children without adding an extra node. So, instead of adding an additional element as a wrapper like we did in the last example, we can throw <React.Fragment> in there to do the job:

class Countries extends React.Component { render() { return ( <React.Fragment> <li>Canada</li> <li>Australia</li> <li>Norway</li> <li>Mexico</li> </React.Fragment> ) }
}

You may think that doesn’t make much difference. But, imagine a situation where you have a component that lists different items such as fruits and other things. These items are all components, and if you are making use of old React versions, the items in these individual components will have to be wrapped in an enclosing tag. Now, however, you can make use of fragments and do away with that unnecessary markup.

Here’s a sample of what I mean:

class Items extends React.Component { render() { return ( <React.Fragment> <Fruit /> <Beverages /> <Drinks /> </React.Fragment> ) }
}

We have three child components inside of the fragment and can now create a component for the container that wraps it. This is much more in line with being able to create components out of everything and being able to compile code with less cruft.

Fragment Shorthand

There is a shorthand syntax when working with Fragments, which you can use. Staying true to its fragment nature, the syntax is like a fragment itself, leaving only only empty brackets behind.

Going back to our last example:

class Fruit extends React.Component { render() { return ( <> <li>Apple</li> <li>Orange</li> <li>Blueberry</li> <li>Cherry</li> </> ) }
}

Question: Is a fragment better than a container div?

You may be looking for a good reason to use Fragments instead of the container div you have always been using. Dan Abramov answered the question on StackOverflow. To summarize:

  1. It’s a tiny bit faster and has less memory usage (no need to create an extra DOM node). This only has a real benefit on very large and/or deep trees, but application performance often suffers from death by a thousand cuts. This is one less cut.
  2. Some CSS mechanisms like flexbox and grid have a special parent-child relationship, and adding divs in the middle makes it harder to maintain the design while extracting logical components.
  3. The DOM inspector is less cluttered.

Keys in Fragments

When mapping a list of items, you still need to make use of keys the same way as before. For example, let’s say we want to pass a list of items as props from a parent component to a child component. In the child component, we want to map through the list of items we have and output each item as a separate entity. Here’s how that looks:

const preload = { "data" : [ { "name": "Reactjs", "url": "https://reactjs.org", "description": "A JavaScript library for building user interfaces", }, { "name": "Vuejs", "url": "https://vuejs.org", "description": "The Progressive JavaScript Framework", }, { "name": "Emberjs", "url": "https://www.emberjs.com", "description": "Ember.js is an open-source JavaScript web framework, based on the Model–view–viewmodel pattern" } ]
} const Frameworks = (props) => { return ( <React.Fragment> {props.items.data.map(item => ( <React.Fragment key={item.id}> <h2>{item.name}</h2> <p>{item.url}</p> <p>{item.description}</p> </React.Fragment> ))} </React.Fragment> )
} const App = () => { return ( <Frameworks items={preload} /> )
}

See the Pen React Fragment Pen by Kingsley Silas Chijioke (@kinsomicrote) on CodePen.

You can see that now, in this case, we are not making use of any divs in the Frameworks component. That’s the key difference!

Render Children Using an Array of Components

The second specific thing that came out of React 16 we want to look at is the ability to render multiple children using an array of components. This is a clear timesaver because it allows us to cram as many into a render instead of having to do it one-by-one.

Here is an example:

class Frameworks extends React.Component { render () { return ( [ <p>JavaScript:</p> <li>React</li>, <li>Vuejs</li>, <li>Angular</li> ] ) }
}

You can also do the same with a stateless functional component:

const Frontend = () => { return [ <h3>Front-End:</h3>, <li>Reactjs</li>, <li>Vuejs</li> ]
} const Backend = () => { return [ <h3>Back-End:</h3>, <li>Express</li>, <li>Restify</li> ]
} const App = () => { return [ <h2>JavaScript Tools</h2>, <Frontend />, <Backend /> ]
}

See the Pen React Fragment 2 Pen by Kingsley Silas Chijioke (@kinsomicrote) on CodePen.

Conclusion

Like the Context API and Error Boundary feature that were introduced in React 16, rendering children components with Fragment and multiples of them with Array Components are two more awesome features you can start making use of as you build your application.

Have you started using these in a project? Let me know how in the comments so we can compare notes. 🙂

The post Render Children in React Using Fragment or Array Components appeared first on CSS-Tricks.

PSA: Yes, Serverless Still Involves Servers.

You clever dog. You’ve rooted it out! It turns out when you build things with serverless technology you’re still using servers. Pardon the patronizing tone there, I’ve seen one-too-many hot takes at this point where someone points this fact out and trots away triumphantly.

And yes, because serverless still involves servers, the term might be a bit disingenuous to some. You could be forgiven for thinking that serverless meant technologies like web workers, which use the client to do things you might have otherwise done on a server and is where the term serverless was headed. Alas, it is not.

What serverless really means:

  • Using other people’s servers instead of running your own. You’re probably already doing that, but serverless takes it to another level where you have no control over the server outside of telling it to run a bit of code.
  • You don’t need to think about scaling — that’s the serverless provider’s problem.
  • You are only paying per execution of your code and not some fixed cost per time.
  • You only worry about your code being misused, but not the security of the server itself.
  • We’re mostly talking about Cloud Functions above, but I’d argue the serverless movement involves anything that allows you to work from static hosting and leverage services to help you with functionality. For example, even putting a Google Form on a static site is within the serverless spirit.

Serverless is about outsourcing a little bit more of your project to companies that are incentivized to do it well. My hope is that someday we can have a conversation about serverless without having to tread this ground every time and spat about the term. I suspect we will. I think we’re almost over the term the cloud as an industry and we’ll jump this hurdle too. It’s worth it when a single word successfully evokes a whole ecosystem.

Wanna know more about serverless? Here’s the tag on CSS-Trick where we’ve talked about it a bunch.

The post PSA: Yes, Serverless Still Involves Servers. appeared first on CSS-Tricks.

Create your own Serverless API

If you don’t already know of it, Todd Motto has this great list of public APIs. It’s awesome if you’re trying out a new framework or new layout pattern and want to hit the ground running without fussing with the content.

But what if you want or need to make your own API? Serverless can help create a nice one for data you’d like to expose for use.

Serverless really shines for this use case, and hopefully this post makes it clear why. In a non-serverless paradigm, we have to pick something like express, we have to set up endpoints, we have to give your web server secured access to your database server, you have to deploy it, etc. In contrast, here we’ll be able to create an API in a few button clicks, with minor modifications.

Here’s the inspiration for this tutorial: I’ve been building a finder to search for new cocktails and grab random one. I originally started using ae public API but realized quickly that I found the contents limiting and wanted to shape my own.

I’m going to use Azure for these examples but it is possible to accomplish what we’re doing here with other cloud providers as well.

Make the Function

To get started, if you haven’t already, create a free Azure trial account. Then go to the portal: preview.portal.azure.com.

Next, we’ll hit the plus sign at the top left and select Serverless Function App from the list. We can then fill in the new name of our function and some options. It will pick up our resource group, subscription, and create a storage account from defaults. It will also use the location data from the resource group. So, happily, it’s pretty easy to populate the data.

Next, we’ll create a new function using HTTP Trigger, and go to the Integrate tab to perform some actions:

What we did was:

  • Give the route template a name
  • Change the authorization level to “Anonymous”
  • Change the allowed HTTP methods to “Selected Method”
  • Select “GET” for the selected method and unchecked everything else

Now, if we get the function URL from the top right of our function, we’ll get this:

https://sdras-api-demo.azurewebsites.net/api/hello

The initial boilerplate testing code that we’re given is:

module.exports = function (context, req) { context.log('JavaScript HTTP trigger function processed a request.'); if (req.query.name || (req.body && req.body.name)) { context.res = { // status: 200, /* Defaults to 200 */ body: "Hello " + (req.query.name || req.body.name) }; } else { context.res = { status: 400, body: "Please pass a name on the query string or in the request body" }; } context.done();
};

Now if we go to the URL below, we’ll see this:

https://sdras-api-demo.azurewebsites.net/api/hello/?name=TacoFace
Says hello TacoFace

There’s more information in this blog post, including API unification with Function Proxies. You can also use custom domains, not covered here.

OK, now that that initial part is all set up, let’s find a place to host our data.

Storing the data with CosmosDB

There are a number of ways to store the data for our function. I wanted to use Cosmos because it has one-click integration, making for a pretty low-friction choice. Get a free account here. Once you’re in the portal, we’ll go to the plus sign in the top left to create a new service and this time select “CosmosDB.” In this case, we chose the SQL version.

We have a few options for how to create our documents in the database. We’re merely making a small example for demo purposes, so we can manually create them by going to Data Explorer in the sidebar. In there, I made a database called CocktailFinder, a collection called Cocktails, and added each document. For our Partition Key, we’ll use /id.

creating a collection

In real practice, you’d probably either want to upload a JSON file by clicking the “Upload JSON” button or follow this article for how to create the files with the CLI.

We can add something in JSON format like this:

{ "id": "1", "drink": "gin_and_tonic", "ingredients": [ "2 ounces gin", "2 lime wedges", "3–4 ounces tonic water" ], "directions": "Add gin to a highball glass filled with ice. Squeeze in lime wedges to taste, then add them to glass. Add tonic water; stir to combine.", "glass": [ "highball", "hurricane" ], "image": "https://images.unsplash.com/photo-1523905491727-d82018a34d75?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=52731e6d008be93fda7f5af1145eac12&auto=format&fit=crop&w=750&q=80"
}

And here is the example with all three that we’ve created, and what Cosmos adds in:

Have the function surface the data

OK, now we’ve got some dummy data to work with, so let’s connect it to our serverless function so we can finish up our API!

If we go back to our function in the portal and click Integrate in the sidebar again, there’s a middle column that called Inputs. Here, we can click on the plus that says “+ New Inputs” and a few options come up. We’ll click the CosmosDB option and “Create.”

Showing in the portal the button to create a connection with CosmosDB

A prompt will come up that asks us to provide information about our Database and Collection. If you recall, the databaseName was CocktailFinder and the collectionName was Cocktails. We also want to use the same partitionKey which was /id. We’ll use all the other defaults.

Now if we go to our function.jso, you can see that it’s now been updated with:

{ "type": "documentDB", "name": "inputDocument", "databaseName": "CocktailFinder", "collectionName": "Cocktails", "partitionKey": "/id", "connection": "sdrassample_DOCUMENTDB", "direction": "in"
}

We’re going to use that inputDocument to update our testing function to reflect that’s what we’re trying to access. I also add in the status and log frequently, but that’s optional.

module.exports = function (context, req) { context.log('JavaScript HTTP trigger function processed a request.'); if (context.bindings) { context.log('Get ready'); context.res = {status: 200, body: context.bindings.inputDocument}; context.log(context.res); } else { context.res = { status: 400, body: "Something went wrong" }; } context.done();
};

Now you can see our function at work!

CORS!

Can’t forget the axios call. I have a really barebones CodePen implementation so that you can see how that might work. In Vue, we’re hooking into the created lifecycle method and making the GET request, in order to output the JSON data to the page.

See the Pen Show API Output, beginning of Vue.js integration by Sarah Drasner (@sdras) on CodePen.

From here, you have all that data to play with, and you can store whatever you like in whatever form you fancy. You can use something like Vue, React, or Angular to create interfaces with the content we stored in our database, and our serverless function creates the API for us. The sky is the limit to what we can create! 🎉

The post Create your own Serverless API appeared first on CSS-Tricks.

Remote Conferences; Bridging the Gap, Clearing the Odds

A few weeks back, I saw one of my esteemed mentors decry the psychological traumas he had experienced, following series and series of refusals at certain embassies.

little girl surprised
“A child concentrating hard at school” by Les Anderson on Unsplash

You would think he went for a contract he did not have the capacity for, but then, you would have been wrong. He needed to impart knowledge. He opted to do so across borders, but then, some realities were harsh.

Borders and geographical constraints can cause a lot of havoc. However, it can only do so, when the full discovery of a better way to impart knowledge across borders has not been made. Video conferencing technology has become handy at times like this. Hence, your traditional seminars, conferences, and talks can easily be achieved from anywhere, regardless of your role.

man on a couch with a computer
Photo by DESIGNECOLOGIST on Unsplash
On a lighter note, these pillows are dope.

Maybe we should not be too ambitious. Maybe we could simply make this article about a one-sided ‘remoteness’, where the attendees are gathered in an offline venue, but then the speakers have a 100% flexibility to speak from anywhere.

For this kind of arrangement, the advantages are many, same as the disadvantages. Let’s start with the disadvantages. For a place not having a very fast internet, the video and audio quality might be abysmal. But that is about that!

For the advantages: a herd of developers or writers are gathered, waiting for a speaker to impart knowledge. So many things would have gone wrong if the speaker was to travel from one location to another. Think about the racism, the mishaps or the thefts. What about the man-hours lost in commuting from one place to the other?

All of these are greatly minimized to a lazy trudge from your bed or kitchen to your computer. Then, the speaker has 5 minutes to the conference, and they are washing their face and checking their teeth. Now he or she is out of time and rushes up with a neatly ironed shirt, on a light brown underpants. Of course, the camera is only built to see the face of the speaker. Convenience is the word!

Visa problems are a thing here in Africa. While a public ban has not been laid on some countries, a lot of resource persons find it difficult to get visa to speak in countries they have a large following, or not.

man putting his head in his hands, looking frustrated, sitting on a pier
Photo by Bruno Aguirre on Unsplash

However, this conferencing arrangement might make your dream come true, if and only if you are able to get up from that cozy bed and turn on your computer in time. You could reach more audience than you expect.

Such an easy life.

For the attendees, it is a Win. Look at it this way; your favorite speakers are just a click away from you! That sounds alluring. There are plenty reasons why your favorite speakers might not make it to you in a totally offline conference, but then everything has been simplified and he or she is simply a button and a good internet-connection away. This offers more mentorship chances and enhances progress. In sum, it makes things easier for your favorite speakers.

a person's hands at a meeting
Photo by Headway on Unsplash

Are you a writer, a developer or a random conference crasher, then you should look out for the next online conference in town. You might just be surprised at the quality of speakers you would be hearing from.

Concatenate is a free conference for Nigerian developers, happening the 9th and 10th of August. The attendees will be in person and the speakers and MC will be both in person and remote from around the world. If you’re near Lagos, register here!

The post Remote Conferences; Bridging the Gap, Clearing the Odds appeared first on CSS-Tricks.