Build a Health Tracking App with React, GraphQL, and User Authentication

By Matt Raible

GraphQL Playground

I think you’ll like the story I’m about to tell you. I’m going to show you how to build a GraphQL API with Vesper framework, TypeORM, and MySQL. These are Node frameworks, and I’ll use TypeScript for the language. For the client, I’ll use React, reactstrap, and Apollo Client to talk to the API. Once you have this environment working, and you add secure user authentication, I believe you’ll love the experience!

Why focus on secure authentication? Well, aside from the fact that I work for Okta, I think we can all agree that pretty much every application depends upon a secure identity management system. For most developers who are building React apps, there’s a decision to be made between rolling your own authentication/authorization or plugging in a service like Okta. Before I dive into building a React app, I want to tell you a bit about Okta, and why I think it’s an excellent solution for all JavaScript developers.

What is Okta?

In short, we make identity management a lot easier, more secure, and more scalable than what you’re used to. Okta is a cloud service that allows developers to create, edit, and securely store user accounts and user account data, and connect them with one or multiple applications. Our API enables you to:

Are you sold? Register for a forever-free developer account, and when you’re done, come on back so we can learn more about building secure apps in React!

Why a Health Tracking App?

In late September through mid-October 2014, I’d done a 21-Day Sugar Detox during which I stopped eating sugar, started exercising regularly, and stopped drinking alcohol. I’d had high blood pressure for over ten years and was on blood-pressure medication at the time. During the first week of the detox, I ran out of blood-pressure medication. Since a new prescription required a doctor visit, I decided I’d wait until after the detox to get it. After three weeks, not only did I lose 15 pounds, but my blood pressure was at normal levels!

Before I started the detox, I came up with a 21-point system to see how healthy I was each week. Its rules were simple: you can earn up to three points per day for the following reasons:

  1. If you eat healthy, you get a point. Otherwise, zero.
  2. If you exercise, you get a point.
  3. If you don’t drink alcohol, you get a point.

I was surprised to find I got eight points the first week I used this system. During the detox, I got 16 points the first week, 20 the second, and 21 the third. Before the detox, I thought eating healthy meant eating anything except fast food. After the detox, I realized that eating healthy for me meant eating no sugar. I’m also a big lover of craft beer, so I modified the alcohol rule to allow two healthier alcohol drinks (like a greyhound or red wine) per day.

My goal is to earn 15 points per week. I find that if I get more, I’ll likely lose weight and have good blood pressure. If I get fewer than 15, I risk getting sick. I’ve been tracking my health like this since September 2014. I’ve lost weight, and my blood pressure has returned to and maintained normal levels. I haven’t had good blood pressure since my early 20s, so this has been a life changer for me.

I built 21-Points Health to track my health. I figured it’d be fun to recreate a small slice of that app, just tracking daily points.

Building an API with TypeORM, GraphQL, and Vesper

TypeORM is a nifty ORM (object-relational mapper) framework that can run in most JavaScript platforms, including Node, a browser, Cordova, React Native, and Electron. It’s heavily influenced by Hibernate, Doctrine, and Entity Framework. Install TypeORM globally to begin creating your API.

npm i -g typeorm@0.2.7

Create a directory to hold the React client and GraphQL API.

mkdir health-tracker
cd health-tracker

Create a new project with MySQL using the following command:

typeorm init --name graphql-api --database mysql

Edit graphql-api/ormconfig.json to customize the username, password, and database.

{
    ...
    "username": "health",
    "password": "pointstest",
    "database": "healthpoints",
    ...
}

TIP: To see the queries being executed against MySQL, change the “logging” value in this file to be “all”. Many other logging options are available too.

Install MySQL

Install MySQL if you don’t already have it installed. On Ubuntu, you can use sudo apt-get install mysql-server. On macOS, you can use Homebrew and brew install mysql. For Windows, you can use the MySQL Installer.

Once you’ve got MySQL installed and configured with a root password, login and create a healthpoints database.

mysql -u root -p
create database healthpoints;
use healthpoints;
grant all privileges on *.* to 'health'@'localhost' identified by 'points';

Navigate to your graphql-api project in a terminal window, install the project’s dependencies, then start it to ensure you can connect to MySQL.

cd graphql-api
npm i
npm start

You should see the following output:

Inserting a new user into the database...
Saved a new user with id: 1
Loading users from the database...
Loaded users:  [ User { id: 1, firstName: 'Timber', lastName: 'Saw', age: 25 } ]
Here you can setup and run express/koa/any other framework.

Install Vesper to Integrate TypeORM and GraphQL

Vesper is a Node framework that integrates TypeORM and GraphQL. To install it, use good ol’ npm.

npm i vesper@0.1.9

Now it’s time to create some GraphQL models (that define what your data looks like) and some controllers (that explain how to interact with your data).

Create graphql-api/src/schema/model/Points.graphql:

type Points {
  id: Int
  date: Date
  exercise: Int
  diet: Int
  alcohol: Int
  notes: String
  user: User
}

Create graphql-api/src/schema/model/User.graphql:

type User {
  id: String
  firstName: String
  lastName: String
  points: [Points]
}

Next, create a graphql-api/src/schema/controller/PointsController.graphql with queries and mutations:

type Query {
  points: [Points]
  pointsGet(id: Int): Points
  users: [User]
}

type Mutation {
  pointsSave(id: Int, date: Date, exercise: Int, diet: Int, alcohol: Int, notes: String): Points
  pointsDelete(id: Int): Boolean
}

Now that your data has GraphQL metadata create entities that will be managed by TypeORM. Change src/entity/User.ts to have the following code that allows points to be associated with a user.

import { Column, Entity, OneToMany, PrimaryColumn } from 'typeorm';
import { Points } from './Points';

@Entity()
export class User {

  @PrimaryColumn()
  id: string;

  @Column()
  firstName: string;

  @Column()
  lastName: string;

  @OneToMany(() => Points, points => points.user)
  points: Points[];
}

In the same src/entity directory, create a Points.ts class with the following code.

import { Entity, PrimaryGeneratedColumn, Column, ManyToOne } from 'typeorm';
import { User } from './User';

@Entity()
export class Points {

  @PrimaryGeneratedColumn()
  id: number;

  @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP'})
  date: Date;

  @Column()
  exercise: number;

  @Column()
  diet: number;

  @Column()
  alcohol: number;

  @Column()
  notes: string;

  @ManyToOne(() => User, user => user.points, { cascade: ["insert"] })
  user: User|null;
}

Note the cascade: ["insert"] option on the @ManyToOne annotation above. This option will automatically insert a user if it’s present on the entity. Create src/controller/PointsController.ts to handle converting the data from your GraphQL queries and mutations.

import { Controller, Mutation, Query } from 'vesper';
import { EntityManager } from 'typeorm';
import { Points } from '../entity/Points';

@Controller()
export class PointsController {

  constructor(private entityManager: EntityManager) {
  }

  // serves "points: [Points]" requests
  @Query()
  points() {
    return this.entityManager.find(Points);
  }

  // serves "pointsGet(id: Int): Points" requests
  @Query()
  pointsGet({id}) {
    return this.entityManager.findOne(Points, id);
  }

  // serves "pointsSave(id: Int, date: Date, exercise: Int, diet: Int, alcohol: Int, notes: String): Points" requests
  @Mutation()
  pointsSave(args) {
    const points = this.entityManager.create(Points, args);
    return this.entityManager.save(Points, points);
  }

  // serves "pointsDelete(id: Int): Boolean" requests
  @Mutation()
  async pointsDelete({id}) {
    await this.entityManager.remove(Points, {id: id});
    return true;
  }
}

Change src/index.ts to use Vesper’s bootstrap() to configure everything.

import { bootstrap } from 'vesper';
import { PointsController } from './controller/PointsController';
import { Points } from './entity/Points';
import { User } from './entity/User';

bootstrap({
  port: 4000,
  controllers: [
    PointsController
  ],
  entities: [
    Points,
    User
  ],
  schemas: [
    __dirname + '/schema/**/*.graphql'
  ],
  cors: true
}).then(() => {
  console.log('Your app is up and running on http://localhost:4000. ' +
    'You can use playground in development mode on http://localhost:4000/playground');
}).catch(error => {
  console.error(error.stack ? error.stack : error);
});

This code tells Vesper to register controllers, entities, GraphQL schemas, to run on port 4000, and to enable CORS (cross-origin resource sharing).

Start your API using npm start and navigate to http://localhost:4000/playground. In the left pane, enter the following mutation and press the play button. You might try typing the code below so you can experience the code completion that GraphQL provides you.

mutation {
  pointsSave(exercise:1, diet:1, alcohol:1, notes:"Hello World") {
    id
    date
    exercise
    diet
    alcohol
    notes
  }
}

Your result should look similar to mine.

You can click the “SCHEMA” tab on the right to see the available queries and mutations. Pretty slick, eh?!

You can use the following points query to verify that data is in your database.

query {
  points {id date exercise diet notes}
}

Fix Dates

You might notice that the date returned from pointsSave and the points query is in a format the might be difficult for a JavaScript client to understand. You can fix that, install graphql-iso-date.

npm i graphql-iso-date@3.5.0

Then, add an import in src/index.ts and configure custom resolvers for the various date types. This example only uses Date, but it’s helpful to know the other options.

import { GraphQLDate, GraphQLDateTime, GraphQLTime } from 'graphql-iso-date';

bootstrap({
  ...
  // https://github.com/vesper-framework/vesper/issues/4
  customResolvers: {
    Date: GraphQLDate,
    Time: GraphQLTime,
    DateTime: GraphQLDateTime
  },
  ...
});

Now running the points query will return a more client-friendly result.

{
  "data": {
    "points": [
      {
        "id": 1,
        "date": "2018-06-04",
        "exercise": 1,
        "diet": 1,
        "notes": "Hello World"
      }
    ]
  }
}

You’ve written an API with GraphQL and TypeScript in about 20 minutes. How cool is that?! There’s still work to do though. In the next sections, you’ll create a React client for this API and add authentication with OIDC. Adding authentication will give you the ability to get the user’s information and associate a user with their points.

Get Started with React

One of the quickest ways to get started with React is to use Create React App. Install the latest release using the command below.

npm i -g create-react-app@1.1.4

Navigate to the directory where you created your GraphQL API and create a React client.

cd health-tracker
create-react-app react-client

Install the dependencies you’ll need to talk to integrate Apollo Client with React, as well as Bootstrap and reactstrap.

npm i apollo-boost@0.1.7 react-apollo@2.1.4 graphql-tag@2.9.2 graphql@0.13.2

Configure Apollo Client for Your API

Open react-client/src/App.js and import ApolloClient from apollo-boost and add the endpoint to your GraphQL API.

import ApolloClient from 'apollo-boost';

const client = new ApolloClient({
  uri: "http://localhost:4000/graphql"
});

That’s it! With only three lines of code, your app is ready to start fetching data. You can prove it by importing the gql function from graphql-tag. This will parse your query string and turn it into a query document.

import gql from 'graphql-tag';

class App extends Component {

  componentDidMount() {
    client.query({
      query: gql`
        {
          points {
            id date exercise diet alcohol notes
          }
        }
      `
    })
    .then(result => console.log(result));
  }
...
}

Make sure to open your browser’s developer tools so you can see the data after making this change. You could modify the console.log() to use this.setState({points: results.data.points}), but then you’d have to initialize the default state in the constructor. But there’s an easier way: you can use ApolloProvider and Query components from react-apollo!

Below is a modified version of react-client/src/App.js that uses these components.

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import ApolloClient from 'apollo-boost';
import gql from 'graphql-tag';
import { ApolloProvider, Query } from 'react-apollo';
const client = new ApolloClient({
  uri: "http://localhost:4000/graphql"
});

class App extends Component {

  render() {
    return (
      <ApolloProvider client={client}>
        <div className="App">
          <header className="App-header">
            <img src={logo} className="App-logo" alt="logo" />
            <h1 className="App-title">Welcome to React</h1>
          </header>
          <p className="App-intro">
            To get started, edit <code>src/App.js</code> and save to reload.
          </p>
          <Query query={gql`
            {
              points {id date exercise diet alcohol notes}
            }
          `}>
            {({loading, error, data}) => {
              if (loading) return <p>Loading...</p>;
              if (error) return <p>Error: {error}</p>;
              return data.points.map(p => {
                return <div key={p.id}>
                  <p>Date: {p.date}</p>
                  <p>Points: {p.exercise + p.diet + p.alcohol}</p>
                  <p>Notes: {p.notes}</p>
                </div>
              })
            }}
          </Query>
        </div>
      </ApolloProvider>
    );
  }
}

export default App;

You’ve built a GraphQL API and a React UI that talks to it – excellent work! However, there’s still more to do. In the next sections, I’ll show you how to add authentication to React, verify JWTs with Vesper, and add CRUD functionality to the UI. CRUD functionality already exists in the API thanks to the mutations you wrote earlier.

Add Authentication for React with OpenID Connect

You’ll need to configure React to use Okta for authentication. You’ll need to create an OIDC app in Okta for that.

Log in to your Okta Developer account (or sign up if you don’t have an account) and navigate to Applications > Add Application. Click Single-Page App, click Next, and give the app a name you’ll remember. Change all instances of localhost:8080 to localhost:3000 and click Done. Your settings should be similar to the screenshot below.

OIDC App Settings

Okta’s React SDK allows you to integrate OIDC into a React application. To install, run the following commands:

npm i @okta/okta-react@1.0.2 react-router-dom@4.2.2

Okta’s React SDK depends on react-router, hence the reason for installing react-router-dom. Configuring routing in client/src/App.tsx is a common practice, so replace its code with the JavaScript below that sets up authentication with Okta.

import React, { Component } from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import { ImplicitCallback, SecureRoute, Security } from '@okta/okta-react';
import Home from './Home';
import Login from './Login';
import Points from './Points';

function onAuthRequired({history}) {
  history.push('/login');
}

class App extends Component {
  render() {
    return (
      <Router>
        <Security issuer='https://{yourOktaDomain}.com/oauth2/default'
                  client_id='{yourClientId}'
                  redirect_uri={window.location.origin + '/implicit/callback'}
                  onAuthRequired={onAuthRequired}>
          <Route path='/' exact={true} component={Home}/>
          <SecureRoute path='/points' component={Points}/>
          <Route path='/login' render={() => <Login baseUrl='https://{yourOktaDomain}.com'/>}/>
          <Route path='/implicit/callback' component={ImplicitCallback}/>
        </Security>
      </Router>
    );
  }
}

export default App;

Make sure to replace {yourOktaDomain} and {yourClientId} in the code above. Your Okta domain should be something like dev-12345.oktapreview. Make sure you don’t end up with two .com values in the URL!

The code in App.js references two components that don’t exist yet: Home, Login, and Points. Create src/Home.js with the following code. This component renders the default route, provides a Login button, and links to your points and logout after you’ve logged in.

import React, { Component } from 'react';
import { withAuth } from '@okta/okta-react';
import { Button, Container } from 'reactstrap';
import AppNavbar from './AppNavbar';
import { Link } from 'react-router-dom';

export default withAuth(class Home extends Component {
  constructor(props) {
    super(props);
    this.state = {authenticated: null, userinfo: null, isOpen: false};
    this.checkAuthentication = this.checkAuthentication.bind(this);
    this.checkAuthentication();
    this.login = this.login.bind(this);
    this.logout = this.logout.bind(this);
  }

  async checkAuthentication() {
    const authenticated = await this.props.auth.isAuthenticated();
    if (authenticated !== this.state.authenticated) {
      if (authenticated && !this.state.userinfo) {
        const userinfo = await this.props.auth.getUser();
        this.setState({authenticated, userinfo});
      } else {
        this.setState({authenticated});
      }
    }
  }

  async componentDidMount() {
    this.checkAuthentication();
  }

  async componentDidUpdate() {
    this.checkAuthentication();
  }

  async login() {
    this.props.auth.login('/');
  }

  async logout() {
    this.props.auth.logout('/');
    this.setState({authenticated: null, userinfo: null});
  }

  render() {
    if (this.state.authenticated === null) return null;
    const button = this.state.authenticated ?
        <div>
          <Button color="link"><Link to="/points">Manage Points</Link></Button><br/>
          <Button color="link" onClick={this.logout}>Logout</Button>
        </div>:
      <Button color="primary" onClick={this.login}>Login</Button>;

    const message = this.state.userinfo ?
      <p>Hello, {this.state.userinfo.given_name}!</p> :
      <p>Please log in to manage your points.</p>;

    return (
      <div>
        <AppNavbar/>
        <Container fluid>
          {message}
          {button}
        </Container>
      </div>
    );
  }
});

This component uses and

Join Scotch's New Community Portal on Spectrum.chat

By Chris Sevilleja

We’ve created a new Scotch community on spectrum.chat. Come on over and join us. We’re just getting started and think this will be a great place to chat.

Join Scotch on Spectrum

Where to Have a Community

We’ve always found that Slack isn’t the best place to have conversations around a specific topic. Things get buried too quickly in a chat room.

We always wanted forums so we could have conversations about

  • tech in general
  • tech news
  • support for articles/courses
  • hang out with like-minded people

If some of you remember, we actually built out forums but they were such a pain to maintain that I dropped them off the face of the Earth.

Why Spectrum?

Spectrum is great because it’s a mashup of forums/chat/Reddit style threads. The other really great part is that you can subscribe to other groups and get a quick view of all your communities.

For instance, I’m subscribed to:

And you can see them all in your Spectrum home page.

Moving Forward

Come in and join us! Start some threads and chat with the Scotch community. Help us test this out so we can see where this could go!

Cheers!

Source:: scotch.io

Customize Payment Solutions with Enhanced API, Sample Code and SDKs

By Anurag Gupta

As developers build sites for merchants, we know that payment processing capabilities are important. But it’s not always easy to set up a payment solution that is not only reliable and secure, but also flexible and tailored to each merchant’s specific needs.

That’s why Authorize.Net has enhanced its toolset for developers, offering a new, streamlined API, better sample code and SDKs, as well as a developer forum for support. The improvements make it easy for you to help your customers get paid — with security, flexibility and scalability. They also simplify PCI compliance and make meeting the requirements easier for merchants.

Below, I’ll walk through the developer center, showing how you can use the improved tools to get your merchants’ payment solutions up and running — with just a few lines of code. If you’d like a refresher on how credit card payments work, check out the seven steps and keep the page open for reference as we go. Now, let’s get started:

Streamlined API enables easier integration

The Authorize.Net API makes it easy to create, capture, refund and void secure payment transactions. Offering both XML or JSON, the API works with our SDKs in six languages: PHP, C#, Java, Python, Ruby and Node.js.

The streamlined API also has the bandwidth to accept payments in every environment, meeting the demands of mobile devices and apps—from food cart to storefront and website to app.

Try the API Reference in a live console

The live console enables you to run a variety of transactions, from charging and authorizing a credit card to issuing refunds, debiting a bank account and more — without signing up for a sandbox account.

1) Run a transaction

You can run a payment transaction using the Authorize.Net API Reference in either JSON or XML, without even setting up a Sandbox account. From the “Payment Transactions” menu on the right side of the screen, you can select from more than a dozen transaction types.

2) Charge a credit card

Charge a credit card by opening the API reference, going to the “Payment Transactions” heading to the right, and selecting, “Charge a Credit Card.” Next, enter your default credentials and hit the “Send” button. You can also edit the sample request in the live console and try APIs with different combinations.

3) Try the sample code

Once you’ve run a payment, you can look at various sample code by clicking on the “Sample Code” tab in the API reference. Choose your desired sample code and language. Then click the Github link and follow the steps to clone the repository. Click download.

4) Demystify error codes

Enter the response code you’re getting from the Authorize.Net Payment Gateway into the Response Code Tool and get a clear translation and suggestions for debugging. For example, if you search for “error 44,” you’ll get the explanation (the transaction has been declined), a list of integration suggestions (using only valid card codes), plus any other relevant suggestions to solve the problem (make sure the card code submitted with the transaction matches the card code on file at the card issuing bank).

5) Test it all out

Use the Testing Guide to trigger specific transaction responses while you’re running tests in the Sandbox. You can test responses including card numbers, bank accounts, CVV responses, NOC and return codes for echecks. The guide enables you to test the most important aspects of your merchant’s payment solution.

Take advantage of SDKs and sample code support

Authorize.Net features APIs, SDKs, and sample code in six different coding languages, which makes integrating with Authorize.Net as easy as possible. Whether you want to build the next breakthrough app or simply allow your merchants to accept a range of credit cards, you’ll find an easy-to-use SDK and sample code in the language of your choice.

To explore our new sample code and SDKs, visit the github link, choose which language you’d like to use, and read the “read me file” to understand how to use it.

Choose the features you need

When using the Authorize.Net API, you can select the features you need to build a unique payment solution for each of your merchants. Choose from the nearly one dozen features below and click each link to learn more about each specific feature:

Achieve PCI Compliance — with Ease

Ensuring that the sites you build are PCI compliant can be a challenge, placing your merchant at risk, as well as complicating your process of setting up a payment platform. The Authorize.Net Accept Suite enables you to build any modern site or app without increasing the PCI burden for merchants. To make that even easier, there’s also an Accept sample app at the github link. To learn more about PCI compliance, read our whitepaper, and to learn about our range of integration options, check out our Accept page.

Rely on the Developer Community

As you’re exploring the streamlined API and improved SDKs and sample code, and using them to customize payment solutions for merchants, visit the Authorize.Net Developer Community to ask questions, network, and learn from your peers.

Source:: scotch.io

Writing Snapshot Tests For React Components With Jest

By John Kariuki

Failing tests

In this tutorial, we will be looking at what snapshot tests are and how we can use snapshot testing to ensure our User Interface does not change without the team knowing about it.

To get started, you will need to familiarize yourself with the following

  1. NodeJS – A JavaScript runtime built on Chrome’s V8 JavaScript engine.
  2. React – A JavaScript library for building delightful UI by Facebook
  3. Jest – A JavaScript testing framework by Facebook.

What Is Snapshot Testing?

Unlike strict Test Driven Development where the standard practice is to write failing tests first then write the code to make the tests pass, Snapshot testing takes a different approach.

To write a snapshot test, you first get your code working, say, a React component, then generate a snapshot of it’s expected output given certain data. The snapshot tests are commited alongside the component and everytime the tests are run. Jest will compare the snapshot to the rendered output for the test.

If the test does not pass, it may mean that there were some unexpected changes on the component that you need to fix, or you made some changes to the component and it’s about time you updated the snapshot tests.

Snapshot testing is meant to be one of many different testing tools. Therefore, you may still need to write tests for your actions and reducers.

Let’s get right into it!

Creating a Simple React Component

To get started, we will create a simple React App using Create React App.

create-react-app ooh-snap
cd ooh-snap
yarn start

We should now have a React app! Let’s go ahead and create a component that we can test. The component that we are going to be creating renders the items props it receives as either a list or as a span element depending on the number of items.

Create a Components folder then add the following Items component

import React from 'react';
import PropTypes from 'prop-types';

/**
 * Render a list of items
 *
 * @param {Object} props - List of items
 */
function Items(props) {
  const { items = [] } = props;

  if (!items.length) {
    // No Items on the list, render an empty message
    return <span>No items in list</span>;
  }

  if (items.length === 1) {
    // One Item in the list, render a span
    return <span>{items[0]}</span>;
  }

  // Multiple items on the list, render a list
  return (
    <ul>
      {items.map(item => <li key={item}>{item}</li>)}
    </ul>
  );
}

Items.propTypes = {
  items: PropTypes.array,
};

Items.defaultProps = {
  items: [],
};

export default Items;

Finally, let’s update App.js to render our Component

import React, { Component } from 'react';
import Items from './Components/Items';

class App extends Component {
  render() {
    const items = [
      'Thor',
      'Captain America',
      'Hulk'
    ];
    return (
      <Items items={items} />
    );
  }
}

export default App;

Effectively, delete App.test.js because we will be adding our own tests in the next section.

Simple, right? Next, let’s go ahead and add our snapshot tests

Writing Snapshot Tests

To get started, install react-test-renderer, a library that enables you to render React components as JavaScript objects without the need of a DOM.

yarn add react-test-renderer

Great, let’s add our first test. To get started, we will create a test that renders the Items component with no items passed down as props.

import React from 'react';
import renderer from 'react-test-renderer';

import Items from './Items';

it('renders correctly when there are no items', () => {
  const tree = renderer.create(<Items />).toJSON();
  expect(tree).toMatchSnapshot();
});

Next, let’s run the tests. Thanks to Create React App, we do not need to set anything else up to run our tests.

yarn test

When your run the tests for the first time, notice that a new snapshot file is created inside a __snapshots__ directory. Since our test file is named Items.test.js, the snapshot file is appropriately named Items.test.js.snap that looks like this.

// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`renders correctly when there are no items 1`] = `
<span>
  No items in list
</span>
`;

Simple, right? The test matches the component’s exact output. Jest uses pretty-format to make the snapshot files human readable.

If you are getting the hang of it, go ahead and create tests for the two other scenarios where there is one item and where there is multiple items, then run the tests.

...
it('renders correctly when there is one item', () => {
  const items = ['one'];
  const tree = renderer.create(<Items items={items} />).toJSON();
  expect(tree).toMatchSnapshot();
});

it('renders correctly when there are multiple items', () => {
  const items = ['one', 'two', 'three'];
  const tree = renderer.create(<Items items={items} />).toJSON();
  expect(tree).toMatchSnapshot();
});

Next, let’s make updates to our component.

Updating Snapshot Tests

To understand why we need snapshot tests, we’ll go ahead and update the Items component and re-run the tests. This, for your dev environment, is a simulation of what would happen when someone on your team makes a change to a component and your CI tool runs the tests.

We will add class names to the span and li elements, say, to effect some styling.

...
/**
 * Render a list of items
 *
 * @param {Object} props - List of items
 */
function Items(props) {
  const { items = [] } = props;

  if (!items.length) {
    // No Items on the list, render an empty message
    return <span className="empty-message">No items in list</span>;
  }

  if (items.length === 1) {
    // One Item in the list, render a span
    return <span className="item-message">{items[0]}</span>;
  }

  // Multiple items on the list, render a list
  return (
    <ul>
      {items.map(item => <li key={item} className="item-message">{item}</li>)}
    </ul>
  );
}
...

Let’s run our tests again with yarn test command in lieu of our changes. Notice anything different?

That’s not good, is it? Jest matched the existing snapshots against the rendered component with the updated changes and failed because there were some additions to our compnent. It then shows a diff of the changes that are introduced to the snapshot tests.

To fix this, for whatever reason, would entirely depend on the changes that were introduced to the snapshot tests.

If the changes are not expected, that’s good, you got it well in advance before it was too late. If the changes were expected, update your snapshot tests and everything is green again.

While Jest is in interactive mode, you can update the snapshot tests by simply pressing u with the options provided. alternatively, you can run jest --updateSnapshot or jest -u.

Watch Mode Options

This will update the snapshots to match the updates we made and our tests will effectively pass.
Passing tests

Go ahead and pick into the snapshots folder to see how the snapshot files changed. Here is the updated empty snapshot snippet.

exports[`renders correctly when there is one item 1`] = `
<span
  className="item-message"
>
  one
</span>
`;

Conclusion

In this tutorial, we have been able to write snapshot tests for a React component. We also updated the component to see the failing tests and eventually update the snapshots to fix the tests.

I hope you can now appreciate how easy it is to iterate and debug your UI changes especially when working as part of a big team.

While we have covered the basics of snapshot tests, there is a lot you could learn on writting better snapshot tests. Do take a look at the Snapshot best practices from the Jest’s documentation to learn more about snapshot testing.

Source:: scotch.io

8 Emmet Tips You Might Not Know

By Chris Sevilleja

Emmet (who remembers when it was called Zen Coding?) is a very useful code editor tool that brings snippets and supercharged shortcuts for generating HTML/markup and even CSS.

Save tons of time in your daily workflow by learning more of Emmet syntax. Also remember that all of these examples will be in plain HTML files, but you can also configure Emmet to be used with React/JSX, Angular templates, Vue templates, and more.

To give you a quick example of Emmet’s main use, expanding an abbreviation into full HTML.

We’ll be typing the following and pressing tab to expand it:

section.hero.is-info>.hero-body>.container>h1.title{Hello!}

The following will be expanded to:

<section class="hero is-info">
  <div class="hero-body">
    <div class="container">
      <h1 class="title">Hello!</h1>
    </div>
  </div>
</section>

Emmet can be found already installed by default on most editors including Sublime Text, VS Code, and WebStorm. For more info on Emmet, check out:

Let’s dig into some of the lesser known features of Emmet. Oh and before we get into it, here’s some info about my setup:

Grouping and Sibling

By using () we can group code together. This works well with the sibling + operator.

Let’s say we wanted two divs to sit next to each other and each has its own children. Notice we’ll be using Bulma CSS classes.

Related Reading: See why Bulma is My Current Favorite CSS Framework

.columns>(.column>.box>h2{I am a box})+(.column>.box>h3{I am another box})

This will be expanded to:

<div class="columns">
  <div class="column">
    <div class="box">
      <h2>I am a box</h2>
    </div>
  </div>
  <div class="column">
    <div class="box">
      <h3>I am another box</h3>
    </div>
  </div>
</div>

Climbing Up

One neat trick Emmet can do is climb back up the tree with ^ if you find yourself nested too far down. I’ve found that using grouping more means I don’t have to climb up the tree. It is useful in some scenarios so it’s good to know.

Here’s another way to achieve our previous example with climbing up:

.columns>.column>.box>h2{Box}^^.column>.box>h3{Box}
<div class="columns">
  <div class="column">
    <div class="box">
      <h2>Box</h2>
    </div>
  </div>
  <div class="column">
    <div class="box">
      <h3>Box</h3>
    </div>
  </div>
</div>

I much prefer the grouping way.

Numbering

When I’m building out some sample HTML, it’s often helpful to use numbering to differentiate sections. (Section 1, Section 2, etc).

Emmet can also help us with numbering using $. I did a Tweet about this the other day and that’s what sparked me to write this post!

p>strong{I am level $ strong!!!!}*10
<p>
  <strong>I am level 1 strong!!!!</strong>
  <strong>I am level 2 strong!!!!</strong>
  <strong>I am level 3 strong!!!!</strong>
  <strong>I am level 4 strong!!!!</strong>
  <strong>I am level 5 strong!!!!</strong>
  <strong>I am level 6 strong!!!!</strong>
  <strong>I am level 7 strong!!!!</strong>
  <strong>I am level 8 strong!!!!</strong>
  <strong>I am level 9 strong!!!!</strong>
  <strong>I am level 10 strong!!!!</strong>
</p>

HTML Tags Expansions

This is something that I really need to use more in my workflow. It gets tedious typing out some of the HTML tags.

I’ll put this in a list since there’s so many to name. Definitely check out the Emmet Cheat Sheet in the HTML section to see all of these.

  • !: Full HTML page
  • a:
  • base:
  • link:css:
  • script:src:
  • input:text:
  • input:t:

Attributes

By using [] we can add attributes to our HTML. For example,

input[type=email].my-input

will become:

<input type="email" class="my-input">

Here’s a cool one using data-attributes and numbering:

div[data-item=$]*10
<div data-item="1"></div>
<div data-item="2"></div>
<div data-item="3"></div>
<div data-item="4"></div>
<div data-item="5"></div>
<div data-item="6"></div>
<div data-item="7"></div>
<div data-item="8"></div>
<div data-item="9"></div>
<div data-item="10"></div>

Wrap with Abbreviation

This is one that I found out about recently and am super excited to add this to my daily toolset.

Select any code and surround it with the tags you want. This requires a little more legwork and you’ll need to open up your Command Palette (cmd + shift + p).

The instructions for VS Code is as follows:

  1. You’ll need to place your cursor on the tag you want to wrap.
  2. Open your command palette with ctrl/cmd + shift + p
  3. Find Emmet: Wrap with Abbreviation
  4. Type in your Emmet abbreviation that will wrap your current tag

Could be very useful!

Tag Balancing

This is also one I found recently that is brilliant. Ever look at an opening HTML tag and wonder where it’s closing tag is? Ever wanted to select everything inside of the opening/closing tags? Tag balancing to the rescue!

  1. Place your cursor inside the tags you want to find
  2. Open the command palette with ctrl/cmd + shift + p
  3. Select Emmet: Balance (Outward)
  4. Do this multiple times to keep expanding outwards

CSS

In addition to markup files, Emmet can be used in CSS. Very useful to expand some things that require a lot of typing. I’ll show off a few of my often used ones:

  • pos: position: relative;
  • d: display: block;
  • m: margin: ;
  • mt: margin-top: ;
  • mb: margin-bottom: ;
  • pw: padding-top: ;
  • pb: padding-bottom: ;
  • bg: background: #000;
  • !: !important
  • @m: @media screen {}
  • c: color: #000;
  • op: opacity: ;

Conclusion

Hopefully you’ve gained a few more Emmet skills to add to your toolset. I’m a big believer of putting in the time to learn the tools we have so that we can be more efficient developers.

Let me know if you liked this post and we’ll do more tips and tricks for ways to improve your workflow.

Source:: scotch.io

Weekly Node.js Update - #23 - 06.08, 2018

By Tamas Kadlecsik

Weekly Node.js Update - #23 - 06.08, 2018

Below you can find RisingStack‘s collection of the most important Node.js news, updates, projects & tutorials from this week:

10 Things I Regret About Node.js – Ryan Dahl

Read Ryan Dahl’s presentation at JSConf EU 2018, on the things he regrets about the way he created Node.js. These include:

  • Promises
  • Security
  • The build system
  • Package.json
  • Node_modules
  • Require without “.js”
  • Index.js

His talk triggered interesting conversations on the web, for example on Hacker News or Reddit. Check out also the thread under Thomas Watson’s tweet.

How we built a nationwide live video streaming service using Node.js Microservices powered by Redis

Carlos Justiniano from Flywheel Sports talks about building light-weight microservices using Redis, at RedisConf18.

Carlos has also contributed to our community website, giving an insightful glance into the following topics:

Building RESTful Web APIs with Node.js, Express, MongoDB, and TypeScript — Part 5

This article is the 5th part of a series on how to build Web APIs with Typescript. It explains various methods to secure your RESTful Web APIs.

Weekly Node.js Update - #23 - 06.08, 2018

The Node.js Event Loop: Not So Single Threaded

It’s true that all JavaScript executed by Node.js is run in a single thread, but this isn’t the case for pure JS. The event loop, written in C++, is multi-threaded! Learn how the event loop works, how it affects performance, and how you can use it your advantage!

Node.js & JavaScript Conferences to Attend in 2018

What conferences should you look forward to in 2018? We collected the best ones focusing on Node.js & Javascript, in Americas & Europe.

Learn Node.js and JavaScript Because It’s Just Plain Fun

Why start learning Node.js? Watch the interview with CJ Silverio on how npm and Node.js work together and how do they help each other to grow synergistically.

Agenda – JS Interactive 2018

JS Interactive 2018 will take place in Vancouver, Canada on October 10-12, 2018. The program will cover a broad spectrum of the JavaScript ecosystem including Node.js, frameworks, best practices and stories from successful end-users. Check out the detailed agenda here.

Microsoft Buys GitHub: The Linux Foundation’s Reaction

Read Jim Zemlin’s thoughtful reflection on the recent announcement of Microsoft purchasing Github for $7.5 billion in stock.
What does it mean of the world of Open Source, and why would Microsoft do this?

June 2018 Security Releases

Node.js will release new versions of all supported release lines around June 12th, 2018 (UTC). These releases will incorporate a number of security fixes.

@v8js 6.7 landed in the Node.js master

The newest, 6.7 Version of the V8 JavaScript engine has landed in the Node.js master.

Worker threads just landed in Node.js!

Lucas Azzola recently tweeted that Worker Threads landed in Node.js. Read the initial implementation of it.

Previous Node.js Updates:

In the previous Weekly Node.js Update, we collected great articles, like

  • Node v10.3.0 (Current) Released;
  • Building a Chat App with Express, React and Socket.io ;
  • Creating an HTTPs server with Node.js and Express;
  • 8 Key Takeaways from the Node.js Survey of 1,600 Engineers (2018);

& more…

We help you to stay up-to-date with Node.js on a daily basis too. Check out our Node.js news page and its Twitter feed!

Source:: risingstack.com

Getting Started with Yoga and Prisma for Building GraphQL Servers

By Chris Nwamba

By now, you have probably heard a lot of buzz about GraphQL going around and how it’s going to replace REST but you don’t even know where to begin. You hear a lot of buzzwords about mutations and queries but what you’re used to is GET and POST requests on your different endpoints to fetch data and make changes to your database. Thinking about making a switch to GraphQL and don’t know where to begin? This article is for you.

In this article, we are going to take a look at how to convert a database to a GraphQL API using Prisma.

Prerequisites

To follow through this article, you’ll need the following:

  • Basic knowledge of JavaScript
  • Node installed on your machine
  • Node Package Manager installed on your machine

To confirm your installations, run the command:

node --version
npm --version

If you get their version numbers as results then you’re good to go!

Using Prisma to connect GraphQL to a database

Prisma is a service that allows you to build a GraphQL server with any database with ease. To get started with using Prisma, you need to install the command line interface first:

npm install -g prisma

This globally installs prisma for future use on your machine. The next thing you need to do is to create a new service. To do this, run the command:

prisma init scotch-prisma-demo

When you run this command, a prompt will be shown for you to decide what server you want to connect to.

For demo purposes, select the Demo Server option and then a browser prompt will be shown to register with Prisma Cloud. After successful login, click the CREATE A NEW SERVICE option and then copy the key required to log in to Prisma from the page.

Head over to your terminal, close the current process if it’s still running and then login to prisma by pasting the command copied from the browser into the terminal:

Login to Prisma

Once you’ve successfully signed in, return to the command line and select the region for your demo server and follow the remaining prompts as shown below:

Creating new Prisma Service

You can also head over here if you want to connect Prisma with own database.

Now that the service has been created, you need to deploy it. To do this, head over to the scotch-prisma-demo directory and run the deploy command:

cd scotch-prisma-demo
prisma deploy

Deploying Prisma Service

Once deployment is complete, on the Prisma Cloud you can see a list of your deployed services:

List of Services on Prisma Cloud

To open the GraphQL API and start sending queries and running mutations, run the command:

prisma playground

Running Sample Queries using Prisma Service

Updating Schema

When the scotch-prisma-demo folder was created, two files were created in the folder

  • prisma.yml – containing the endpoint and datamodel for the server.
  • datamodel.graphql – Containing the schema for the server.

Edit the datamodel.graphql file to look like this:

type User {
    id: ID! @unique
    name: String!
}

This means the schema will contain the ID and name for the user. To update the schema, run the command:

prisma deploy

Using Yoga and Prisma Binding to interact with Prisma Service

In the last section, we saw how to use Prisma to turn a database into GraphQL API and then run Queries and mutations from the playground. Here’s the thing though. In a real-life application, leaving all this functionality to anyone who has access to the Prisma means that the client has the entire database exposed to them and this is not good.

To to this, Prisma has the graphql-yoga and prisma-binding which allow you to build a GraphQL server on top of the Prisma service by connecting the resolvers of the GraphQL server to Prisma’s GraphQL API using Prisma binding.

In the scotch-prisma-demo folder initialize a node project using the command:

npm init -y

This automatically creates a package.json file for your project

Installing the necessary modules

To continue building the graphql server, we will need to install the following modules by running the command:

npm install graphgql-yoga prisma-binding

Reorganize File Structure

Run the following commands:

mkdir prisma
mv datamodel.graphql prisma/
mv prisma.yml prisma/
mkdir src
touch src/index.js
touch src/schema.graphql

Creating Application Schema

The GraphQL server needs to have a Schema that helps identify the operations that can be carried out on the server. For this application, edit the src/schema.graphql to look like this:

type Query{
    user(id: ID!): User
}

type Mutation {
    signup(name: String!): User!
}

In this case, the schema allows for the following:

  • Fetch a single user based on its id
  • Signup a user to the system

Downloading Prisma Database Schema

If you look at the schema definition above, you can see that the User is not defined. Ideally, you could redefine the User type in the schema but since there already exists a definition in the Prisma service created earlier, we will use that instead to prevent us from having multiple locations for one definition.

Install the GraphQL CLI by running:

npm install -g graphql-cli

and then create a .graphqlconfig in the root directory of the project and update it as follows:

touch .graphqlconfig.yml
projects:
    app:
        schemPath: src/schema.graphql
        extensions:
            endpoints:
            default: http://localhost:4000
    prisma:
        schemaPath: src/generated/prisma.graphql
        extensions:
            prisma: prisma/prisma.yml

You can download the Prisma schema by running the following command:

graphql get-schema --project prisma

Then, update the src/schema.graphql to look like this:

import User from './generated/prisma.graphql'

type Query{
    user(id: ID!): User
}

type Mutation {
    signup(name: String!): User!
}

You have the Prisma schema downloaded in the /src/generated/prisma.graphql file.

Instantiating Prisma bindings and Implementing Resolvers

The next thing to do is to ensure that Prisma’s GraphQL API can be accessed by the resolvers using the prisma-binding. To do this, update the index.js file to look like this:

// src/index.js
const { GraphQLServer } = require('graphql-yoga')
const { Prisma } = require('prisma-binding')

const resolvers = {
    Query: {
        user: (_, args, context, info) => {
            // ...
        }
    },
    Mutation: {
        signup: (_, args, context, info) => {
            // ...
        }
    }
}

const server = new GraphQLServer({
    typeDefs: 'src/schema.graphql',
    resolvers,
    context: req => ({
        req,
        prisma: new Prisma({
            typeDefs: 'src/generated/prisma.graphql',
            endpoint: 'PRISMA_ENDPOINT',
        }),
    }),
})
server.start(() => console.log(`GraphQL server is running on http://localhost:4000`))

Note that the PRISMA_ENDPOINT can be obtained from your /prisma/prisma.yml file.

Update the resolvers in your application by adding the following into your index.js file:

// src/index.js
[...]

const resolvers = {
    Query: {
        user: (_, args, context, info) => {
            return context.prisma.query.user(
                {
                    where: {
                        id: args.id,
                    },
                },
                info
            )
        }
    },
    Mutation: {
        signup: (_, args, context, info) => {
            return context.prisma.mutation.createUser(
                {
                    data: {
                        name: args.name,
                    },
                },
                info
            )
        }
    }
}

[...]

Update your package.json file as follows:

{
    "name": "scotch-prisma-demo",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
    "start": "node src/index.js",
    "test": "echo "Error: no test specified" && exit 1"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "dependencies": {
    "graphql-yoga": "^1.14.7",
    "prisma-binding": "^2.0.2"
    }
}

Here, we added the start script to the project. Now, you can run the application by using this command:

npm start

This starts the server and the playground for use. When you head over to the browser and navigate to localhost:4000, you get the following:

Running a Mutation in the Playground

Running a Query in the Playground

Now that we have built the GraphQL server over the Prisma Service, the playground no longer connects directly to the Prisma Endpoint but to the application itself. With this, the client is restricted to only performing actions that have been defined in the new schema on the server.

Conclusion

In the article, we have seen how to create a Prisma service that converts a database to a GraphQL API and how to use GraphQL Yoga and Prisma Binding to build a GraphQL server on the service for use by client applications. Here’s a link to the GitHub repository if interested. Feel free to leave a comment below.

Source:: scotch.io