Monthly Archives: October 2017

Realtime GraphQL UI Updates in React with Apollo.

By John Kariuki

Introduction

This is the fourth and final part of a 4-part series of articles explaining the implementation of GraphQL on an Express Server and similarly in a React client using Apollo. In this article we look at how to maintain realtime UI updates after implementing different GraphQL updates that result in either creation, update or deletion of data on the server side. For part 1, 2 and 3, refer to the links:

Updating the client state after a mutation

In the second part of this series of articles, we had to reload the page to see the new channel that had been created; there was no automatic re-rendering of the UI. This is because Apollo has no way of knowing that the mutation we made has anything to do with the channels query that renders our list. Only the server knows that, but it has no way of notifying our client. To update the client after a mutation, we can opt for on of the following three ways:

  • Refetch queries that could be affected by the mutations.
  • Manually updating the client state based on the mutation result.
  • Using GraphQL subscriptions.

Refetch

Refetches are the simplest way to force a portion of your cache to reflect the information available to your server. Essentially, a refetch forces a query to immediately hit the server again, bypassing the cache. The result of this query, just like all other query results, updates the information available in the cache, which updates all of the query results on the page. To tell Apollo Client that we want to refetch the channels after our mutation completes, we pass it via the refetchQueries option on the call to mutate. We will reuse the channelsListQuery by exporting it from ChannelsList.jsx and import it in CreateChannel.jsx.

//  src/app/components/ChannelList/ChannelList.jsx
export const channelsListQuery = gql`
   query ChannelsListQuery {
     channels {
       id
       name
     }
   }
 `;

We then pass the query via refetchQueries option in mutate.

...
// src/app/components/CreateChannel/CreateChannel.jsx
...
import { channelsListQuery } from '../ChannelList/ChannelList';
const CreateChannel = ({mutate}) => {
    const handleKeyUp = (evt) => {
      if (evt.keyCode === 13) {
        evt.persist();
        mutate({
          variables: { name: evt.target.value },
          refetchQueries: [ { query: channelsListQuery }]
        })
        .then( res => {
          evt.target.value = '';
        });
      }
  };
  ...

When we create a new channel right now, the UI shows it without reloading the page.

This is a good step but the downside is that this method will not show the updates if the request was made by another client. You won’t find out until you do a mutation of your own and refetch the list from the server or reload the page which we are trying to avoid. To make the application more realtime, Apollo provides a feature that allows us to poll queries within an interval. To enable this feature, we pass the pollInterval option with our channelsListQuery.

//  src/app/components/ChannelList/ChannelList.jsx
...
const ChannelsListWithData = graphql(channelsListQuery, { options: { pollInterval: 5000 }})(ChannelsList);
...

Creating a new channel from another client now updates our list of channels after 5 seconds, not the best way of doing it but a step in making the application realtime.

Updating the Store

To update the store based on a client action, Apollo provides a set of tools to perform imperative store updates: readQuery,writeQuery, readFragment and writeFragment. The client normalizes all of your data so that if any data you previously fetched from your GraphQL server is updated in a later data fetch from your server then your data will be updated with the latest truth from your server. Apollo exposes these functions via the update property in mutate. Using update gives you full control over the cache, allowing you to make changes to your data model in response to a mutation in any way you like.

To implement it, we replace the refetchQueries option with the following call to update.

// src/app/components/CreateChannel/CreateChannel.jsx
...
mutate({
          variables: { name: evt.target.value },
          update: (store, { data: { addChannel } }) => {
            // Read the data from the cache for this query.
            const data = store.readQuery({query: channelsListQuery });
            // Add our channel from the mutation to the end.
            data.channels.push(addChannel);
            // Write the data back to the cache.
            store.writeQuery({ query: channelsListQuery, data });
          }
        })
...

As soon as the mutation completes, we read the current result for the channelsListQuery out of the store, append the new channel to it, and tell Apollo Client to write it back to the store. Our ChannelsList component will automatically get updated with the new data. There’s still a delay which is a result of the network request. Apollo provides, optimistic UI, a feature that allows your client code to easily predict the result of a successful mutation even before the server responds with the result providing a fater user experience. This is possible with Apollo if the client can predict an optimistic response for the mutation.

Optimistic UI

To enable optimistic UI, we add the optimisticResponse property to mutate call. This “fake result” will be used to update active queries immediately, in the same way that the server’s mutation response would have done. The optimistic patches are stored in a separate place in the cache, so once the actual mutation returns, the relevant optimistic update is automatically thrown away and replaced with the real result. Since the server generates the channel Id’s which we use as keys in rendering the list, we will generate random keys to use before the server response and retain the channel name since we know what we expect. Finally, we also have to specify the __typename to make sure Apollo Client knows what kind of object it is.

// src/app/components/CreateChannel/CreateChannel.jsx
...
       variables: { name: evt.target.value },
          optimisticResponse: {
             addChannel: {
               name: evt.target.value,
               id: Math.round(Math.random() * -1000000), // Generate a random ID to avoid conflicts.
               __typename: 'Channel',
             },
          },
          update:
...

After this addition, creating a new channel instantly shows the channel on the list with no delays. These updates have not been confirmed by the server yet. For purposes of development and knowledge, we can choose to show the user which items are pending confirmation. As you can notice, we used negative values for the random Id’s; this enables us to differentiate already confirmed channels which have positive Id’s. We could add a CSS class to highlight channels awaiting confirmation.

 ...
 return <ul className="list-group">
     { channels.map( ch => <li className={ "list-group-item " + (ch.id < 0 ? "pending" : "")} key={ch.id}>{ch.name}</li> ) }
   </ul>;
...

For a brief moment, with the addition of pending class, the new item appears red before turning to black. We can make this behaviour more defined so as to observe it for development pusrposes by simulating a latency in the network. In the following snippet, we fake a 3-second network delay that allows us to see the UI changes clearly. We use applyMiddleware which allows us to modify the request made over the netWorkInterface.

// src/app/app.jsx
...
networkInterface.use([{
  applyMiddleware(req, next) {
    setTimeout(next, 3000);
  },
}]);
...

Initially.

After 3 seconds.

Subscriptions

Use of GraphQL subscriptions is a way to push data from the server to the clients that choose to listen to real time messages from the server. Subscriptions are similar to queries in that they specify a set of fields to be delivered to the client, but instead of immediately returning a single answer, a result is sent every time a particular event happens on the server.

A common use case for subscriptions is notifying the client side about particular events, for example the creation of a new object, updated fields and so on.
This section relies on server-side implementation of subscriptions and I would advise going through it for maximum gain.
The first step to adding subscriptions to our client is to set up the WebSocket connection that the client and server will communicate over. Forming and maintaining the WebSocket connection will be the job of the Apollo network interface, defined in client/src/App.js. To add WebSocket support to our existing interface, we will construct a GraphQL Subscription client and merge it with our existing network interface to create a new interface that performs normal GraphQL queries over HTTP and subscription queries over WebSockets. The most popular transport for GraphQL subscriptions today is subscriptions-transport-ws which we can install using:

# Note the package version. Future updates will change the implementation.
yarn add subscriptions-transport-ws@0.8.2   # Alternatively npm i subscriptions-transport-ws@0.8.2

We also remove the following part used to demonstrate refetching of queries and polling to show the real power of real-time updates.

//src/app/components/CreateChannel/CreateChannel.jsx
...
 refetchQueries: [ { query: channelsListQuery }]  // Remove this part to disable query refetching feature.
...

We edit the following part to disable polling.

//src/app/components/ChannelList/ChannelList.jsx
...
 const ChannelsListWithData = graphql(channelsListQuery, { options: { pollInterval: 5000 }})(ChannelsList);
...

Edit the above to:

//src/app/components/ChannelList/ChannelList.jsx
...
 const ChannelsListWithData = graphql(channelsListQuery)(ChannelsList);
...

Trying to add a new channel now in our app does not reflect the changes until we refresh the page and that is what we expect.

Then, initialize a GraphQL subscriptions transport client and merge it with our existing network interface.

 //src/app/app.jsx
...
import { SubscriptionClient, addGraphQLSubscriptions } from 'subscriptions-transport-ws';
...
const networkInterface = createNetworkInterface({
  uri: 'http://localhost:7900/graphql',
});

const wsClient = new SubscriptionClient(`ws://localhost:7900/subscriptions`, {
  reconnect: true
});

// Extend the network interface with the WebSocket
const networkInterfaceWithSubscriptions = addGraphQLSubscriptions(
  networkInterface,
  wsClient
);

To enable subscriptions throughout our application, we use networkInterfaceWithSubscriptions as the Apollo Client’s network interface:

const client = new ApolloClient({
   networkInterface: networkInterfaceWithSubscriptions // Use the subscriptions interface as the client interface.
});

When we inspect our network in the browser, it shows that we are subscribed to a channel.

Our queries and mutations will now go over HTTP as normal, but subscriptions will be done over the WebSocket transport.

Listening for Messages

Now that we can use GraphQL Subscriptions in our client, the next step is to use subscriptions to detect the creation of new channels. Our goal here is to use subscriptions to update our React views to see new channels as they are added. We begin by writing the subscription.

// src/app/components/ChannelList/ChannelList.jsx
...
// Create a subscription
const channelSubscription = gql`
    subscription Channels {
     channelAdded {
       id
       name
     }
    }
`
...

With GraphQL subscriptions your client will be alerted on push from the server and we can use the data sent along with the notification and merge it directly into the store (existing queries are automatically notified). We can accomplish this using subscribeToMore function available on every query result in react-apollo. The update function gets called every time the subscription returns.

Before we start, we have to refactor our client/src/components/ChannelDetails.js component to be a full ES6 class component instead of just a function, so that we can use the React lifecycle events to set up the subscription.

In componentWillMount we add a functionaliity that will subscribe using subscribeToMore and update the query’s store with the new data using updateQuery. The updateQuery callback must return an object of the same shape as the initial query data, otherwise the new data won’t be merged.

//src/app/components/ChannelList/ChannelList.jsx
componentWillMount() {
   this.props.data.subscribeToMore({
     document: channelSubscription,   // Use the subscription
     updateQuery: (prev, {subscriptionData}) => {
       if (!subscriptionData.data) {
         return prev;
       }

       const newChannel = subscriptionData.data.channelAdded;
       // Add check to prevent double adding of channels.
      if (!prev.channels.find((channel) => channel.name === newChannel.name)) {
         let updatedChannels = Object.assign({}, prev, { channels : [...prev.channels, newChannel ] });
         return updatedChannels;
       } else {
         return prev;
       }
     }
   });
 }
 render() {
 ...

Testing

We can now test our application by opening two browser windows at http://localhost:7800/ side by side. Adding a channel in either window immediately shows the new channel in the adjacent window.

Conclusion

We have explored different ways in which we can update our client to avoid page refreshes and large data requests and we can conclude that using subscriptions is the fastest and most efficient way of achieving this.

Source:: scotch.io

Demystifying Vue Lifecycle Methods

By Chris Nwamba

Using components in your application is one thing but understanding how they work and knowing their lifecycle (when they are created, added to your DOM, updated or destroyed) is very important. You can hook into each of these component lifecycle methods to perform specific application tasks. In this post, I will explain the various lifecycle methods in Vue and how they work as well as when they should be implemented.

What are Lifecycle methods?

Lifecycle methods serve as a viewpoint into how our built components work behind the scenes. They provide you with methods that enable you trigger different actions at different junctures of a component’s lifecycle. They also auto-bind to your component so that you can use the component’s state and methods. Actions of lifecycle methods can be broken down into four categories:

  • Creation
  • Mounting
  • Updating
  • Destruction

Creation

Creation methods are used to perform actions on your component before adding it to the DOM. They should be used when configuring your component during both client as well as server side rendering. Creation methods are implemented using beforeCreate() and created() hooks.

beforeCreate(): The beforeCreate() hook observes data and initialization events in your component. Here, data is still not reactive and events that occur during the component’s lifecycle have not been set up yet. Check out the example below:

  new Vue({
    data: {
     x: 5
    },
    beforeCreate: function () {
      // `this` points to the view model instance
      console.log('x is: ' + this.x)
    }
  })
     // x is: undefined

created(): The created() hook is invoked when Vue has set up events and data observation. Here, events are active and access to reactive data is enabled though templates have not yet been mounted or rendered. Check out the code block below:

  new Vue({
    data: {
     x: 5
    },
    created: function () {
      // `this` points to the view model instance
      console.log('x is: ' + this.x)
    }
  })
     // x is: 5

Mounting

The most used methods when working with components, mounting methods let you access your component immediately before and after it is rendered the first time. They should be used if the DOM of your component needs to be modified immediately before or after it is initially rendered.

As mounting hooks do not run during server side rendering, they shouldn’t be used for fetching data for components on initialization. created() methods are best suited for that purpose.

beforeMount(): The beforeMount() method is invoked after our template has been compiled and our virtual DOM updated by Vue. After this, the $el property is added to the Vue instance, the native DOM is updated and the mounted() method is invoked.

  new Vue({
    beforeMount: function () {
      // `this` points to the view model instance
      console.log(`this.$el is yet to be created`)
    }
  })

mounted(): The mounted() method gives you access to templates and enables interaction with the DOM. It is mostly used for fetching data for your component and modifying the DOM to integrate other libraries and frameworks asides Vue. Let’s take a look at the code block below:

<div id="app">
    <p>I'm text inside the component.</p>
</div>

Using the mounted() method to fetch this data from the DOM:

  new Vue({
    el: '#app',
    mounted: function() {
      console.log(this.$el.textContent) 
    }
  })
  // I'm text inside the component.

Created vs Mounted

Updating

Updating methods are useful for debugging. They are called whenever a reactive property used by your component changes or re-renders. The component’s DOM would have been updated when this hook is called so you can use updating methods to perform DOM dependent operations. It’s advised you don’t use updating methods to change state, computed properties or watchers are best fit for that instead.

beforeUpdate(): This method runs after data changes on your component and the update cycle begins right before the DOM is patched and re-rendered. It allows you get the new state of any reactive data on your component before it is rendered. Check out the code block below:

<div id="app">
  <p>{{counter}}</p>
</div>

Interaction with our Vue instance:

  new Vue({
    el: '#app',
    data() {
      return {
        counter: 0
      }
    },
     created: function() {
      setInterval(() => {
        this.counter++
      }, 1000)
    },

    beforeUpdate: function() {
      console.log(this.counter) // Logs the counter value every second, before the DOM updates.
    }
  })

updated(): The updated() method runs after data changes on your component and the DOM re-renders. Take a look at the example below:

<div id="app">
  <p ref="dom">{{counter}}</p>
</div>

Interacting with our Vue instance gives:

  new Vue({
    el: '#app',
    data() {
      return {
        counter: 0
      }
    },
     created: function() {
      setInterval(() => {
        this.counter++
      }, 1000)
    },
    updated: function() {
      console.log(+this.$refs['dom'].textContent === this.counter) // Logs true every second
    }
  })

Destruction

Destruction methods are used in the final moments of a component’s lifecycle. They allow you perform actions such as cleanup when your component is destroyed and are executed when your component is torn down and removed from the DOM.

beforeDestroy(): This method is executed right before your component is destroyed. Here your component is still fully present and functional. If you need to cleanup events, beforeDestroy() is the best time to do that. Check out the code block below:

new Vue ({
  data() {
    return {
      coolMethods: 'Lifecycle methods are awesome!'
    }
  },

  beforeDestroy: function() {
    // Perform the teardown procedure for coolMethods which in this case is nothing.
    this.coolMethods = null
    delete this.coolMethods
  }
})

destroyed(): This method is called after your component has been destroyed, its directives have been unbound and its event listeners have been removed. The destroyed() method can be used to do any last minute cleanup or informing a remote server that the component was destroyed. Check out the example below:

  import destructionUpdateBot from './destruction-site'
  new Vue ({
    destroyed: function() {
      console.log(this) // Nothing to show here
      destructionUpdateBot.bomb('Target acquired.')
    }
  })

Summary

That’s it. That’s all Vue lifecycle methods are and nothing more. Now you should be able to visualize the journey of a Vue instance whenever it is initialized and as well customize you own code using these various hooks or methods should the need arise. You can always look up Vue’s documentation for other methods and properties to use alongside lifecycle methods when creating your components.

Source:: scotch.io

Node.js Weekly Update - October 27

By Tamas Kadlecsik

Node.js Weekly Update - October 27

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

Node v8.8.0 (Current), 24 October

Notable Changes:

  • crypto:
    • expose ECDH class
  • http2:
    • http2 is now exposed by default without the need for a flag
    • a new environment variable NODE_NO_HTTP2 has been added to allow userland http2 to be required
    • support has been added for generic Duplex streams
  • module:
    • resolve and instantiate loader pipeline hooks have been added to the ESM lifecycle
  • zlib:
    • CVE-2017-14919 – In zlib v1.2.9, a change was made that causes an error to be raised when a raw deflate stream is initialized with windowBits set to 8. On some versions this crashes Node and you cannot recover from it, while on some versions it throws an exception. Node.js will now gracefully set windowBits to 9 replicating the legacy behavior to avoid a DOS vector.

A Node v8.8.1 fix was released on 26, October to fix timeout with null handle issue.

Rich Trott (@trott)No V8 commit can land if it breaks Node.js

Keynote by @fhinkel tells everyone that V8 policy now is that no V8 commit can land if it breaks Node.js. 🎉

— Rich Trott (@trott) October 4, 2017

Testing a Node.js API

Have you just built an API with Node.js? If you’d really like to make a progress as a developer, you’ll have to start testing your APIs.

In this tutorial, you will learn how to write a Node.js API test. Dive in!

Google APIs Node.js Client

Node.js client library is supported by Google to assess Google APIs.
This library on Github is still in maintenance mode, as they are still working on some bugs and adding new features to meet the requirements of or accessing Google APIs. Code on!

V8 Release 6.3

This week, V8 version 6.3 has been announced, which is in beta until its release in coordination with Chrome 63 Stable in several weeks. V8 v6.3 is filled with all sorts of developer-facing goodies, such as improved speed, memory consumption, and debugging, as well as new ECMAScript language features.

Microsoft adds multithreading to Node.js for compute-heavy apps

Microsoft’s beta Napa.js runtime is offering multithreaded support for the Node.js server-side JavaScript platform, to provide the flexibility of JavaScript with a speedy performance akin to C++’s.

By introducing multithreading to Node.js, the Napa.js runtime can more easily handle computation-intensive tasks.

Serverless Node with AWS Lambda, API Gateway and DynamoDB

Lambda and AWS API Gateway provide a quick and efficient way of building RESTful APIs. Developers can setup a lambda (i.e., a function) in JavaScript, or any other major programming language, and trigger it by an HTTP request.

How to do it? Check it out in this tutorial. You will create a lambda CRUD microservice which saved data in a DB.

On Node.js, Go and concurrency

Ryan Dahl, the creator of Node.js said the following while he was talking about Node’s concurrency model:

[…] I think Node is not the best system to build a massive server web. I would use Go for that. And honestly, that’s the reason why I left Node. It was the realization that: oh, actually, this is not the best server-side system ever.

What does this mean for the Node.js community? Is this the end of the Node-era?

Our Beginner Node.js Tutorials are now available in Russian too

We are happy to announce that our most comprehensive Node.js tutorial series is now available in 2 languages: English and Russian.

By eliminating the language barrier, we hope that a lot of new developers can learn about the fantastic possibilities that Node.js provides.

Check it out!

Token based authentication in Node.js with Passport, JWT and bcrypt

When you develop an API, most of the times you’ll need part or all of its endpoints to require authentication. How to do that using Node.js?

A combination of passport.js with JWT and bcrypt is one of the best ways to implement it. Time to go stateless!

Previously in the Node.js Weekly Update

In the previous Node.js Weekly Update we collected the latest news on Node.js like DOS security vulnerability, and checked how to build a site with OpenID Connect, how to document your Node.js API, introduced StdLib sourcecode, and witnessed an epic battle between Javascript vs. Java. Click if you missed it!

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

Deploying AdonisJS Apps to DigitalOcean

By Chimezie Enyinnaya

In my last post I showed how to deploy AdonisJS apps to Heroku. In this tutorial, I’ll be showing you how to deploy your AdonisJS application to Digital Ocean. We’ll also be deploying the task list app we built earlier on.

Prerequisites

This tutorial assumes the following:

Create Droplet

Login to your Digital Ocean account and create a new droplet (server). We’ll be going to with One-click apps. Select NodeJS as shown below:

Next, we’ll choose the $10 plan. Though the task list app will work perfectly on the $5 plan, but we won’t be able to install the NPM dependencies because the NPM requires at least 1GB RAM for installing dependencies. Though there is a way around this by creating swap memory which is beyond the scope of this tutorial.

Next, select a datacenter region, we’ll go with the default:

Next, add your SSH key. If you have already added SSH keys to Digital Ocean before, you can choose from those:

If not you will need to click on the New SSH Key button to add a new SSH key. You can get your SSH key by running the command below on your local computer:

cat ~/.ssh/id_rsa.pub

The command above will print your SSH key on the terminal, which you can then copy and paste in the SSH Key Content field. Also, give your SSH key a name.

Finally, choose a hostname for the droplet and click the Create button.

After some couple of seconds, you’ll have your new server up and running on Ubuntu 16.04 and NodeJS version 6.11.2.

Also, note the IP address of the server as we’ll be using it to access the server.

Create Non-root User

Before we start configuring the server for the task app, let’s quickly create a non-root user which we’ll use henceforth for the rest of the tutorial.

Tip: As a security measure, it is recommended to carry out tasks on your server as a non-root user with administrative privileges.

First, we need to login to the server as root. We can do that using the server’s IP address:

ssh root@IP_ADDRESS

Once we are logged in to the server, we can move on to create a new user:

adduser mezie

This will create a new user called mezie, you can name the user whatever you like. You will be asked a few questions, starting with the account password.

Having created the new user, we need to give it administrative privileges. That is, the user will be able to carry out administrative tasks by using sudo command.

usermod -aG sudo mezie

The command above adds the user mezie to sudo group.

Now the user can run commands with superuser privileges.

Setup SSH Key For The New User

You need to copy your public key to your new server. Enter the command below on your local computer:

cat ~/.ssh/id_rsa.pub

This will print your SSH key to the terminal, which you can then copy.

For the new user to login to the server with SSH key, we must add the public key to a special file in the user’s home directory.

Still logged in as root on the server, enter the following command:

su - mezie

This will temporarily switch to the new user. Now you’ll be in your new user’s home directory.

Next, we need to create a new directory called .ssh and restrict its permission:

mkdir ~/.ssh
chmod 700 ~/.ssh

Next, within the .ssh directory, create a new file called authorized_keys:

touch ~/.ssh/authorized_keys

Next, open the file with vim:

vim ~/.ssh/authorized_keys

Next, paste your public key (copied above) into the file. To save the file, hit esc to stop editing, then :wq and press ENTER.

Next, restrict the permissions of the authorized_keys file with this command:

chmod 600 ~/.ssh/authorized_keys

Type the command below to return to the root user:

exit

Now your public key is installed, and you can use SSH keys to log in as your user.

To make sure you can login as the new user with SSH. Enter the command below in a new terminal on your local computer:

ssh mezie@IP_ADDRESS

If all went well, you’ll be logged in to the server as the new user with SSH.

The rest of the tutorial assumes you are logged in to the server with the new user created (mezie in my case).

Updating to Latest NodeJS Version

Notice the server currently have NodeJS version 6.11.2, but AdonisJS v4.0 requires NodeJS v8.0 or greater. So we need to upgrade it to the latest version. We’ll do that using a NPM package called n. This will allow us to install multiple versions for NodeJS which we can easily choose from as the case may be. Enter the commands below on the server:

// install n package globally
npm install -g n

// install latest version of Node.js which v8.6.0 as at this tutorial
n latest

If we check NodeJS version we’ll still see v6.11.2. Though we already installed the latest version, for the this to take effect enter the command below:

bash

This is will simply start another bash instance. It’s more like restarting bash.

Install Nginx

We’ll install Nginx as the webserver to be used for reverse proxy which will allow us to access the app directly with an IP address or domain instead of tacking port to the IP address. Eg. 102.123.83.29:5000.

sudo apt-get update
sudo apt-get install nginx

Because we chose One-click apps while creating our droplet, ufw firewall is setup for us and running. Now, we need to open firewall for only HTTP since we are not concerned with SSL in this tutorial:

sudo ufw allow 'Nginx HTTP'

Install MySQL

Next, we need to install MySQL and set up database and user to be used by the task list app.

sudo apt-get install mysql-server

Enter a root password when prompted. Next, we’ll finish configuring MySQL:

sudo mysql_secure_installation

Enter the necessary options when prompted.

With the MySQL setup, we need to create a database and a user.

First, login to the MyQSL server:

mysql -u root -p

Provide the root password you enter above while installing MySQL. Once you are logged in, create a new database:

CREATE DATABASE adonis_tasks;

Also, create a new user:

CREATE USER 'mezie'@'localhost' IDENTIFIED BY 'password';

Replace mezie and password with your user and password respectively.

Next, we need to grant the new user priviledges to the tables on the new database:

GRANT ALL ON adonis_tasks.* TO 'mezie'@'localhost';

For the changes to take effect, run:

FLUSH PRIVILEGES;

With the initial setups out of the way, let’s now focus on the app itself. We are going to clone the app unto the server directly in the user’s home directory (that is, /home/mezie in my case):

git clone https://github.com/ammezie/adonis-tasks.git

Next, we install the dependencies:

cd adonis-tasks
npm install --production

Next, create .env file:

vim .env

And paste the following into it:

// .env

HOST=127.0.0.1
PORT=3333
NODE_ENV=production
CACHE_VIEWS=true
APP_KEY=WdpmKSRNxJhejBxxwvgtdGbPM0JBlRxm
DB_CONNECTION=mysql
DB_HOST=localhost
DB_DATABASE=adonis_tasks
DB_USER=YOUR_DB_USER
DB_PASSWORD=YOUR_DB_PASSWORD

Save the file and exit vim.

Next, we need to run database migrations. First, let’s install the Adonis CLI so we can make use of it great features:

npm i -g @adonisjs/cli

Once installed, let’s run the migrations:

    adonis migration:run --force

Because we are on production, we have to use the --``force flag.

Test The App

Before we process, let’s test to make sure the app is working fine. Start the app with the command below:

npm start

Then in a new terminal, enter the command below:

curl http://127.0.0.1:3333

You should get an output as below:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Task List</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.5.1/css/bulma.min.css" />
</head>
<body>
    <section class="section">
        <div class="container">
            <div class="columns">
                <div class="column is-8 is-offset-2">
    <div class="box">
          <h2 class="title">New Task</h2>

          <form action="/tasks" method="POST">
              <input type="hidden" name="_csrf" value="4f2uYvxk-j_OR-vX1D1_DfRb7KanGrhKwV-s">

              <div class="field has-addons">
                  <div class="control is-expanded">
                      <input class="input" type="text" name="title" value="" placeholder="Task title">
                  </div>
                  <div class="control">
                      <button type="submit" class="button is-primary">
                          Add Task
                      </button>
                  </div>
              </div>
          </form>
      </div>
      <div class="box">
          <h1 class="title">Task List</h1>
          <table class="table is-bordered is-striped is-narrow is-fullwidth">
              <thead>
                  <tr>
                     <th>SN</th>
                     <th>Title</th>
                     <th>Action</th>
                  </tr>
              </thead>
              <tbody>
                      <td colspan="3" class="has-text-centered">No task created yet!</td>
              </tbody>
          </table>
      </div>
                </div>
            </div>
        </div>
  </section>
</body>
</html>

This indicates the app is up and running fine. But whenever the app crashes we’ll need to manually start the app again which is not a recommended approach. So, we need a process manager to help us with starting the app and restarting it whenever it crashes. We’ll use PM2 for this.

Install PM2

We’ll install it globally through NPM:

sudo npm install -g pm2

With PM2 installed, we can start the app with it:

pm2 start server.js

Once the app is started you will get an output from PM2 indicating the app has started.

To launch PM2 on system startup or reboot, enter the command below:

pm2 startup systemd

You’ll get the following output:

[PM2] Init System found: systemd
[PM2] To setup the Startup Script, copy/paste the following command:
sudo env PATH=$PATH:/usr/local/bin /usr/local/lib/node_modules/pm2/bin/pm2 startup systemd -u mezie --hp /home/mezie

Copy and run the last command from the output above:

sudo env PATH=$PATH:/usr/local/bin /usr/local/lib/node_modules/pm2/bin/pm2 startup systemd -u mezie --hp /home/mezie

Now PM2 will start at boot up.

Set Up Nginx as a Reverse Proxy Server

Finally, we set up Nginx as a reverse proxy server. To this, run:

sudo vim /etc/nginx/sites-available/default

Within the server block you should have an existing location / block. Replace the contents of that block with the following configuration:

// /etc/nginx/sites-available/default

...
location / {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-NginX-Proxy true;
    proxy_pass http://127.0.0.1:3333;
    proxy_set_header Host $http_host;
    proxy_cache_bypass $http_upgrade;
    proxy_redirect off;
}

Save and exit vim.

Test to make sure there are no syntax errors in the configuration by running:

sudo nginx -t

Then restart Nginx:

sudo systemctl restart nginx

Now you should be able to access the app with your IP_ADDRESS. You should get something similar to the image below:

Conclusion

That’s it. You have seen how to deploy AdonisJS app to Digital Ocean.

Source:: scotch.io

Extending Vue Components with Mixins

By Chris Nwamba

When it’s a side project or something little, the DRY concept may not be tightly upheld. Yikes it’s just a “simple demo”, nothing large. When we begin to build large chunks of code not necessarily production level, thoughts of reusability and maintainability begin to come in. Must these methods be repeated? How do we replace this and that with functions? When using frameworks such as Vue, even with its ease of use and gradual learning curve, it becomes cumbersome to write and keep track of repetitive options in components. These options may be component data or hook methods such as “created”, “mounted” and even “methods”. This is where Mixins come in.

Mixins in Vue, gives us the ability to wrap our reusable options in a “variable container” which can be used anywhere in the script. And by anywhere, even globally, but that would be treated with caution.

What is a Mixin?

As the name goes – “Mix – In”, Mixin gives us a way to distribute reusable functionality in Vue components. These reusable functions are merged with existing functions. In our Vue component, we specify the mixin object with:

const myMixin = {
  created(){
    console.log("It works!")
  }
}
var app = new Vue({
  el: '#root',
  mixins: [myMixin]
})// It works!

Using mixins, whichever options specified in the mixin are immediately merged with the Vue component’s options. Multiple mixins can be specified in the mixin array of the component. Once specified, all mixin options are imported to the parent component.

Merging Options and Conflicts

Now we may think, what if there are conflicting options between hook functions from a mixin and that of the parent component, which takes precedence? When mixins are passed in components, Vue moves all hook functions such as created and mounted imported via the mixin into an array of options, including the options of the parent component. The parent component options are called last.

const myMixin = {
  created(){
    console.log("Welcome aboard")
  }
}

new Vue({
  el: '#root',
  mixins:[myMixin],
  created(){
    console.log("Ahoy mate!")
  }
})
//Welcome aboard
//Ahoy mate!

There are options which expect objects, like the methods object. In such cases where there is a conflict between options, the component options take precedence.

const myMixin = {
  created(){
    console.log("Welcome aboard")
  },
  methods:{
    name(){
      this.myName = prompt("Input Name")
    }
  }
}

new Vue({
  el:"#root",
  mixins:[myMixin],
  data:{
    myName:""
  },
  created(){
    console.log("Ahoy mate!")
  },
  methods:{
    name(){
      this.myName = "Christian John"
      console.log(this.myName)
    }
  }
})

//Console Logs
> Welcome aboard
> Ahoy mate!
> Christian John

Notice how the name() method in the mixin was disregarded during the conflict. The prompt to input name never runs.

Note: The Component Options are always right.

Here is a Codepen demo of a simple Vue counter app using mixin:

Global Mixins

In some cases, there is the need to extend the functionality of Vue or apply an option to all Vue components available in our application. Feels a bit scary? Yeah, mixins can be applied globally to affect all components in Vue.

Vue.mixin({
  created(){
  console.log("We wilding!")
  }
})

new Vue({
  el: '#data'
})

//Console
> We wilding!

The global mixin is created above the Vue instance, and we would have the mixin options spread across all components with the console running wild. This can be useful, during test, and debugging or third party libraries maybe, but we can see the potential harm that could be done if misused.

Using Mixins in CLI Development Mode

Using the Vue CLI, mixins can be specified anywhere in the project folder but preferably within /src/mixins for ease of access. Once mixins are created in a .js file and exposed with the export keyword, they can be imported in any component with the import keyword and its file path.

src/mixins/numeroUno.js

export const ={
  created(){
    console.log("Welcome aboard")
  },
  methods:{
    name(){
      this.myName = prompt("Input Name")
    }
  }
}

In the component, wherever it is in our project folder, we import the mixin object:

import {numeroUno} from <file path>

export default{
  name:'main',
  mixin:[numeroUno]
}

Even though we are importing a mixin object, lifecycle options are still available via the mixin and can be used in the component imported to.

Conclusion

Don’t Repeat Yourself. In a bid to follow this rule, we have seen how the power of Vue mixins can be utilized to minimize code and maximize the functionality of components. This comes in handy when multiple components are defined across our application with similar options. Components are created in the first place to introduce reusability, mixins are created to introduce reusability in our components. Mixins can also be created globally to function across all Vue components, such access if wrongly used can be dastardly.

Source:: scotch.io

The New CSS Layout By Rachel Andrew

Ben Nadel reviews The New CSS Layout by Rachel Andrew. This book offers a technical introduction to the Flexbox and Grid specifications (among others), demonstrating how these new layout techniques offer powerful solutions for robust and responsive page structure. Definitely a must-read for anyone whose CSS mental model is getting old….

Source:: bennadel.com