Categories
JavaScript Vue

Making Code Reusable with Vue.js Mixins

Vue.js is an easy to use web app framework that we can use to develop interactive front end apps.

In this article, we’ll look at how to define and use mixins to make code reusable.

Basics

We can define a mixin by writing some simple code that consists of an object with some properties of components as follows:

src/index.js :

const appMixin = {  
  created() {  
    this.hello();  
  },  
  methods: {  
    hello() {  
      this.message = "hi";  
    }  
  }  
};
new Vue({  
  el: "#app",  
  mixins: [appMixin],  
  data: {  
    message: ""  
  }  
});

index.html :

<!DOCTYPE html>  
<html>  
  <head>  
    <title>App</title>  
    <meta charset="UTF-8" />  
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>  
  </head>  
  <body>  
    <div id="app">  
      {{message}}  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>

In the code above, we defined the mixin appMixin by assigning it to an object with the structure that are the same as the Vue instance.

Therefore, hello gets called when the Vue instance is created since we have the created hook in appMixin .

Then in the template, we display the message , so we get hi on the screen.

Other properties we can put include methods , components , and directives . They’ll all be merged into the object we pass into new Vue or the component options object.

If there’s anything that’s the same, the component’s options will take priority over the items in the mixin.

For example, if we have the following:

src/index.js :

const appMixin = {  
  created() {  
    this.hello();  
  },  
  methods: {  
    hello() {  
      this.message = "hi";  
    }  
  }  
};
new Vue({  
  el: "#app",  
  mixins: [appMixin],  
  data: {  
    message: ""  
  },  
  created() {  
    this.hello();  
  },  
  methods: {  
    hello() {  
      this.message = "foo";  
    }  
  }  
});

index.html :

<!DOCTYPE html>  
<html>  
  <head>  
    <title>App</title>  
    <meta charset="UTF-8" />  
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>  
  </head>  
  <body>  
    <div id="app">  
      {{message}}  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>

Then foo is displayed since the methods in the Vue instance takes precedence over the methods in the mixin.

We can also use the Vue.extend method to create a new component as follows:

src/index.js :

const appMixin = {  
  created() {  
    this.hello();  
  },  
  methods: {  
    hello() {  
      this.message = "hi";  
    }  
  }  
};
const Component = Vue.extend({  
  mixins: [appMixin],  
  el: "#app"  
});

new Component();

index.html :

<!DOCTYPE html>  
<html>  
  <head>  
    <title>App</title>  
    <meta charset="UTF-8" />  
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>  
  </head>  
  <body>  
    <div id="app">  
      {{message}}  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>

Vue.extend works the same way as new Vue that we have above.

The same merging mechanism is used with Vue.extend() .

Option Merging

We can adjust how items are merged by selecting the appropriate strategy for merging.

For example, data objects are merged recursively, with component’s data taking priority in case of conflicts.

src/index.js :

const mixin = {  
  data() {  
    return {  
      message: "hi",  
      foo: "abc"  
    };  
  }  
};

new Vue({  
  el: "#app",  
  mixins: [mixin],  
  data() {  
    return {  
      message: "bye",  
      bar: "def"  
    };  
  }  
});

index.html :

<!DOCTYPE html>  
<html>  
  <head>  
    <title>App</title>  
    <meta charset="UTF-8" />  
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>  
  </head>  
  <body>  
    <div id="app">  
      {{message}} {{foo}} {{bar}}  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>

We see bye abc def displayed since message is in both the component and the mixin, and the component takes precedence.

foo and bar are only in the mixin and component respectively, so they’re both merged into the same data object.

Hooks with the same name are merged into an array so that they all will be called. Mixin hooks will be called the component’s own hooks.

So if we have:

src/index.js :

const mixin = {  
  mounted() {  
    console.log("mixin hook called");  
  }  
};

new Vue({  
  el: "#app",  
  mixins: [mixin],  
  mounted() {  
    console.log("component hook called");  
  }  
});

We see:

mixin hook called  
component hook called

in the console.log output.

Options that expect object values like methods , components , and directives are merged into the same object. The component’s options will take priority when there’re conflicts in the objects.

For example, if we have:

src/index.js :

const mixin = {  
  methods: {  
    foo() {  
      console.log("foo");  
    }  
  }  
};

const vm = new Vue({  
  el: "#app",  
  mixins: [mixin],  
  methods: {  
    foo() {  
      console.log("bar");  
    }  
  }  
});  
vm.foo();

We’ll see bar logged since the component’s foo method takes precedence over the mixin ‘s foo method.

The same merging strategies are used in Vue.extend().

Conclusion

Mixins allow us to create code that can be included in multiple components.

They’re merged by taking component’s methods , components , and directives taking precedence over the mixin’s items in these properties.

Data are merged together as well, with component’s data taking precedence if the same key exists in both places.

Hooks are merged into an array, with the mixin’s hook being called before the component’s hook if they have the same name.

Categories
Express JavaScript Nodejs

Verifying JSON Web Tokens with Express-JWT

With the use of single-page apps and API-only back end, JSON web tokens (JWTs) have become a popular way of adding authentication capabilities to our apps.

In this article, we’ll look at how to verify JSON web tokens with Express-JWT.

Installation

express-jwt is available as a Node package. To install it, we run:

npm install express-jwt

Usage

We can use the jwt function that’s included with the express-jwt package to verify a token.

jwt is a middleware function, so we don’t have to create our own middleware to verify the token.

For example, we can use the jwt function as follows:

const express = require('express');  
const jsonwebtoken = require('jsonwebtoken');  
const jwt = require('express-jwt');  
const app = express();
const secret = 'secret';
app.post('/auth', (req, res) => {  
  const token = jsonwebtoken.sign({ foo: 'bar' }, secret);  
  res.send(token);  
})
app.get('/protected', jwt({ secret }), (req, res) => {  
  res.send('protected');  
})
app.listen(3000, () => console.log('server started'));

In the code above, we called jsonwebtoken.sign to issue a token in the auth route.

Then we can call the protected route by putting Bearer and then our token in the Authorization request header.

An example Authorization header would be:

Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJpYXQiOjE1Nzk0NzczMDd9.QW7FOvyJQ36dir0199nJTv07VhlNo9\_cItGTkdyJeK8

If the token isn’t valid or isn’t present, then we would get an error.

We can also check other fields like audience or issuer as follows:

const express = require('express');  
const jsonwebtoken = require('jsonwebtoken');  
const jwt = require('express-jwt');  
const app = express();
const secret = 'secret';  
const audience = 'http://myapi/protected';  
const issuer = 'http://issuer';
app.post('/auth', (req, res) => {  
  const token = jsonwebtoken.sign({ foo: 'bar' }, secret, { audience, issuer });  
  res.send(token);  
})
app.get('/protected', jwt({ secret, audience, issuer }), (req, res) => {  
  res.send('protected');  
})
app.listen(3000, () => console.log('server started'));

In the code above, we added audience and issuer to the object in the 3rd argument of the sign method call, which holds the options that we want to add to the token issued.

Then in the protected route, we added the jwt middleware with the audience and issuer in the options object that we passed into jwt .

If the token has a secret , audience , and issuer that match what the code has, then the protected route returns the protected response. Otherwise, we get an error.

We can verify a token that’s generated with a Base64 encoded secret as follows:

const express = require('express');  
const jsonwebtoken = require('jsonwebtoken');  
const jwt = require('express-jwt');  
const app = express();
const secret = 'secret';
app.post('/auth', (req, res) => {  
  const token = jsonwebtoken.sign({ foo: 'bar' }, new Buffer(secret, 'base64'));  
  res.send(token);  
})
app.get('/protected', jwt({ secret: new Buffer(secret, 'base64') }), (req, res) => {  
  res.send('protected');  
})
app.listen(3000, () => console.log('server started'));

In the code above, we have the new Buffer(secret, ‘base64’) passed to the second argument of the sign method, which generates a token from a Base64 encoded secret.

Then in the protected route handler, we can call the jwt middleware function with the same secret to verify the token.

To verify a token generated with an RSA private key, we can write the following:

const express = require('express');  
const jsonwebtoken = require('jsonwebtoken');  
const jwt = require('express-jwt');  
const fs = require('fs');  
const app = express();
const publicKey = fs.readFileSync('public.pub');
app.post('/auth', (req, res) => {  
  const privateKey = fs.readFileSync('private.key');  
  const token = jsonwebtoken.sign({ foo: 'bar' }, privateKey, { algorithm: 'RS256' });  
  res.send(token);  
})
app.get('/protected', jwt({ secret: publicKey }), (req, res) => {  
  res.send('protected');  
})
app.listen(3000, () => console.log('server started'));

The token is generated in the auth route by reading the private key from a file on the file system and then using that to sign the token with the sign method.

Then we can use the public key that corresponds to the private key that was used to generate the token to verify the token by writing:

jwt({ secret: publicKey })

To access the decoded token, we can use the req.user property as follows:

const express = require('express');  
const jsonwebtoken = require('jsonwebtoken');  
const jwt = require('express-jwt');  
const app = express();  
const secret = 'secret';app.post('/auth', (req, res) => {  
  const token = jsonwebtoken.sign({ foo: 'bar' }, secret);  
  res.send(token);  
})app.get('/protected', jwt({ secret }), (req, res) => {  
  res.send(req.user);  
})app.listen(3000, () => console.log('server started'));

In the protected route, we returned req.user as the response. Then we should get something like:

{  
    "foo": "bar",  
    "iat": 1579478314  
}

in the response content.

We can change what property the decoded token is attached to by setting the requestProperty property as follows:

app.get('/protected', jwt({ secret, requestProperty: 'auth' }), (req, res) => {  
  res.send(req.auth);  
})

Then we get the same response as the previous example.

Conclusion

We can use the express-jwt middleware to verify our JSON web tokens.

It takes a secret and other token options like audience and issuer and then sets the decoded token to the Express request object if verification is successful.

If verification isn’t successful, then an error is returned.

It supports both symmetric and asymmetric crypto algorithms.

Categories
JavaScript Vue

Vue.js Templates: Modifiers and Shorthands

Vue.js is an easy to use web app framework that we can use to develop interactive front-end apps.

In this article, we’ll look at modifiers for directives and some useful template shorthands.


Modifiers

Modifiers are used for binding a directive in a special way.

Event modifiers

For example, the .prevent modifier for the v-on directive will automatically run event.preventDefault on the event handler function that’s set as the value.

The .prevent modifier can be used as follows:

<form v-on:submit.prevent="onSubmit"> ... </form>

Then, event.preventDefault() will be run when the onSubmit handler is run, before the rest of the code for onSubmit is run.

Other event modifiers include:

  • .stop
  • .capture
  • .self
  • .once
  • .passive

.stop runs event.stopPropagation() before the rest of the event handler code is run.

.capture lets us capture the event. That is, when we run the event handler in an inner element, then the same event handler will also run in the outside elements.

For example, if we have the following in src/index.js:

And the following in index.html:

Then, when we click Click Me, we’ll see the “clicked” alert box since the onClick handler is called on the parent div element.

.self will only trigger the event handler if the event.target is the element itself.

.once will trigger an event handler at most once.

For example, if we have the following in src/index.js:

And the following in index.html:

Then we only see the “clicked” alert box once even though we click “Click me” multiple times.

.passive will set the addEventListener’s passive option to true. passive set to true means that preventDefault() will never be called.

It’s used for improving performance on mobile devices.

Model modifiers

v-model has modifiers. They’re:

  • .lazy
  • .number
  • .trim

The .lazy modifier will make the model sync after the change event instead of the input event.

For example, when we have src/index.js:

new Vue({  
  el: "#app",  
  data: { msg: "" }  
});

And write the following in index.html:

Then we only see msg rendered when we move focus away from the input.

The .number modifier will automatically cast whatever is inputted in an input to a number.

For instance, if we have the following in src/index.js:

new Vue({  
  el: "#app",  
  data: { num: 0 }  
});

And the following in index.html:

Then we’ll get a number for num.

The .trim modifier will trim whitespace from whatever is inputted.

We can use it as follows:

<input v-model.trim="msg" type="number" />

Shorthands

There are shorthands for some directives.

v-bind

We can shorten v-bind: to :. For example, we can rewrite:

<a v-bind:href="url">Link</a>

To:

<a :href="url">Link</a>

We can also put in a dynamic argument if we use Vue 2.6.0 or later:

<a :[key]="url">Link</a>

v-on

We can shorten v-on: to @.

For example, we can shorten:

<a v-on:click="onClick">Click me</a>

To:

<a @click="onClick">Click me</a>

Since Vue 2.6.0, we can also use dynamic arguments as follows:

<a @[event]="onClick">Click me</a>

: and @ are valid characters. Also, they won’t appear in the final markup. Shorthands are totally optional. But we’ll appreciate them when we have to type them in a lot.


Conclusion

Some directives have modifiers that are associated with them.

The v-on directive has multiple modifiers for controlling how event handlers are called.

Also, the v-model directive has some modifiers to let us convert input to numbers automatically or trim whitespace from inputs.

v-on and v-bind also have shorthands. v-on: can be shortened to @, and v-bind: can be shortened to :.

Directive arguments also work with shorthands.

Categories
Express JavaScript

Guide to the Express Response Object — Sending Things

The Express response object lets us send a response to the client.

Various kinds of responses like strings, JSON, and files can be sent. Also, we can send various headers and status code to the client in addition to the body.

In this article, we’ll look at various properties of the response object, including send , sendFile , and sendStatus .

Methods

res.send([body])

We can use the res.send method to send an HTTP response.

The body parameter can be a Buffer object, string, a plain object or an array.

For example, we can send a binary response by writing:

const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res, next) => {  
  res.send(Buffer.from('foo'));  
})  
app.listen(3000);

To send JSON, we can pass in an object:

const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))app.get('/', (req, res, next) => {  
  res.send({ foo: 'bar' });  
})  
app.listen(3000);

We can also send HTML by passing in a string:

const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))app.get('/', (req, res, next) => {  
  res.send('<p>foo</p>');  
})  
app.listen(3000);

We can send the response code in addition to the send method:

const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res, next) => {  
  res.status(404).send('not found');  
})
app.listen(3000);

We can set the response header before sending our response:

const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res, next) => {  
  res.set('Content-Type', 'text/html');  
  res.send(Buffer.from('<p>foo</p>'))  
})  
app.listen(3000);

send also works with an array:

const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res, next) => {  
  res.send([1, 2, 3]);  
})
app.listen(3000);

Then we get [1,2,3] .

res.sendFile(path [, options] [, fn])

We can use the sendFile to send a file with various options specified in the options object.

An absolute path is required for the path for sendFile to work.

For example, we can use it as follows:

const express = require('express');  
const path = require('path');  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res, next) => {  
  const options = {  
    root: path.join(__dirname, 'files'),  
    dotfiles: 'deny',  
    headers: {  
      'x-timestamp': Date.now(),  
      'x-sent': true  
    }  
  }  
  res.sendFile('foo.txt', options);  
})  
app.listen(3000);

The code above sets the root path in the options so that we don’t have to construct the absolute path every time we call sendFile .

The following properties can be added to the options object:

  • maxAge — sets the max-age property of the Cache-Control header in milliseconds or a string in ms format
  • root — root directory for relative filenames
  • lastModified — sets the Last-Modified header to the last modified date of the file on the OS. Set to false to disable it.
  • headers — an object containing HTTP response headers to serve with the file.
  • dotfiles — option for serving dotfiles. Possible values are allow , deny , or ignore .
  • acceptRanges — enable or disable accepting range requests
  • cacheControl — enable or disable setting Cache-Control response header
  • immutable — enable or disable immutable directive in the Cache-Control header. If it’s enabled, the maxAge option should be specified to enable caching. The immutable directive will prevent supported clients from making conditional requests during the life of maxAge option to check if a file has changed.

We can also pass in a callback to handle errors as the last argument:

const express = require('express');  
const path = require('path');  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res, next) => {  
  const options = {  
    root: path.join(__dirname, 'files'),  
    dotfiles: 'deny',  
    headers: {  
      'x-timestamp': Date.now(),  
      'x-sent': true  
    }  
  }  
  res.sendFile('foo.txt', options, err => next(err));  
})  
app.listen(3000);

res.sendStatus(statusCode)

We can send an HTTP response status code with this method. We just have to pass in a number.

If an unsupported status code is specified the code will still be sent and a string version of it will be sent in the response body.

For example, if we have:

const express = require('express');  
const path = require('path');  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res, next) => {  
  res.sendStatus(200)  
})  
app.listen(3000);

Then we get back OK .

If we write the following:

const express = require('express');  
const path = require('path');  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res, next) => {  
  res.sendStatus(900)  
})  
app.listen(3000);

We get 900 since we sent an unsupported response code.

Conclusion

We can send responses in various ways with Express. The most generic one is send , which lets us send both textual and binary data. We can set headers to indicate what we’re sending.

sendFile sends a file response with the absolute file path of the file on the server. We can specify various options for the file we send.

The sendStatus method lets us send an HTTP response code only. We can use it to send both supported and unsupported response codes.

Categories
Flow JavaScript

JavaScript Type Checking with Flow — Typeof Types

Flow is a type checker made by Facebook for checking JavaScript data types. It has many built-in data types we can use to annotate the types of variables and function parameters.

In this article, we’ll look at typeof types, which are types that are derived from other values.

The JavaScript Typeof Operator

In JavaScript, the typeof operator is mostly useful for checking the type of primitive values. For example, it works for numbers, booleans, and strings:

typeof 2 === 'number'  
typeof true === 'boolean'  
typeof 'abc' === 'string'

For objects, it always returns 'object' :

typeof { foo: 'abc' } === 'object'

Flow’s Typeof Operator

Flow’s typeof operator is much more useful. It can be used to return the value of any type.

For example, it can get the type for numbers as follows:

let num = 42;  
let num2: typeof num = 3.14;

It’ll fail when we assign values of any other type to it, like the following:

num2 = 'foo';

The benefit of Flow’s typeof operator is that it can also be used for objects. For instance, if we have the following object:

let obj = { foo: 1, bar: true };

Then we can use the typeof operator to assign the obj object as a type of another object as follows:

let obj2: typeof obj = { foo: 1, bar: false };

As long as we have all the properties of obj with the same data type, then it satisfies the requirement of the typeof obj type.

We can do the same for arrays as follows:

let foo = [1, 2, 3];  
let bar: typeof foo = [3, 2, 1];

typeof foo will infer that the type of foo is a number array, so we can assign another number array to bar .

Type Inference

The typeof operator does type inference implicitly. When we use literal values with Flow, then the inferred type is the primitive that the value belongs to.

For example, 1 would be a number . We can override the inferred type by explicitly asserting the type of variable we define as follows:

let num1: 1 = 1;

Then assigning num1 to anything other than 1 will fail:

let num2: typeof num1 = 3;

The code above will give us an error.

Typeof’s Nominal Type Check

Like other parts of Flow, the typeof operator also checks type nominally. This means that it checks the name rather than the structure. Therefore, even though 2 types have the same structure, but when their names are different, then they’re considered different.

For example, if we write:

class Foo {  
  foo(val: number) { }  
}

class Bar {  
  foo(val: number) {  }  
}

Then the following assignment would work:

let x: typeof Foo = Foo;

because both types have the same name, but:

let y: typeof Foo = Bar;

would fail even though Foo and Bar have the same structure since the have different names.

With Flow’s typeof operator, we can identify types of objects in addition to primitives. It’s consistent with Flow’s nominal type system in that it also checks the name by its name instead of the structure.

Also, the typeof operator can infer types from the data that’s assigned to a variable. For example, if a variable is a number array, then using the typrof operator on that array will return number array as the type.