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
JavaScript Rxjs

More Useful Rxjs Transformation Operators

RxJS is a library for reactive programming. Creation operators are useful for generating data from various data sources to be subscribed to by Observers.

In this article, we’ll look at some RxJS transformation operators like concatMapTo, expand, exhaust, and exhaustMap operators.

concatMapTo

The concatMapTo operator takes the source value of the Observable and maps each value to the same inner Observable.

It takes up to 2 arguments. The first is the innerObservable, which is the Observable to map each value from the originating Observable to.

The second argument is a resultSelector function to let us pick the results.

Each originating Observable’s emitted value is mapped to the given innerObservable regardless of the source value. Then flatten those resulting Observables into one Observable. which is the returned Observable.

Each new innerObservable’s emitted are concatenated together with the other ones’ values.

If the source values arrive endlessly and faster than the corresponding inner Observables can complete then it’ll result in memory issues since there’ll be a large amount of data amassed waiting to be subscribed to.

For example, we can use it as follows:

import { fromEvent, interval } from "rxjs";  
import { take, concatMapTo } from "rxjs/operators";
const clicks = fromEvent(document, "click");  
const result = clicks.pipe(concatMapTo(interval(1000).pipe(take(5))));  
result.subscribe(x => console.log(x));

The code above will get the click events from the document and then emit 0 after 1 second, then wait for another second and emit, up to 4.

exhaust

The exhaust operator converts a higher-level Observable, which are Observables that emits Observables, into the first-order Observable by emitted inner Observables while previous inner Observable hasn’t been completed.

The result would be that the values from all the Observables are flattened and emitted by one Observable, which is the one returned by this operator.

For example, we can write:

import { interval, of } from "rxjs";  
import { exhaust, map, take } from "rxjs/operators";
const observable = of(1, 2, 3);  
const higherOrder = observable.pipe(map(ev => interval(1000).pipe(take(5))));  
const result = higherOrder.pipe(exhaust());  
result.subscribe(x => console.log(x));

In the code above, we have an observable Observable that emits 1, 2, and 3. The values emitted by observable are mapped to inner Observables using the map operator into interval(1000).pipe(take(5) .

Since the inner Observables that aren’t completed are dropped by the exhaust operator, we’ll get that interval(1000).pipe(take(5) is only emitted once since only the first instance of it is started. Then we get that a number is emitted every second, starting with 0 and stops at 4.

exhaustMap

The exhaustMap operator also takes the first inner Observable that are mapped from the originating Observable like the exhaust operator. The difference is that it takes a function that lets us map the values of the origination Observable’s emitted values into another Observable, but only taking the first emitted Observable by this operator.

For example, if we have the following code:

import { interval, of } from "rxjs";  
import { take, exhaustMap } from "rxjs/operators";
const observable = of(1, 2, 3);  
const result = observable.pipe(exhaustMap(ev => interval(1000).pipe(take(5))));  
result.subscribe(x => console.log(x));

We get the same result as exhaust, but we don’t have to pipe and map the emitted values of observable into a new Observable. Instead, we combined everything together with the exhaustMap operator.

expand

The expand operator recursively projects each source value to an Observable which is then merged into the output Observable.

It takes 3 arguments, which is the project function, which applies to the items emitted by the source Observable or the output Observable and returns a new Observable.

The second argument is the concurrency, which is an optional argument for the maximum number of input Observables being subscribed to concurrently. It defaults to Number.POSITIVE_INFINITY .

The last argument is the optional scheduler object, which is the scheduler we can use to time the emission of values.

One simple example usage of this operator would be as follows:

import { of } from "rxjs";  
import { expand, delay, take } from "rxjs/operators";
const powersOfTwo = of(1, 2, 3).pipe(  
  expand(x => of(x).pipe(delay(1000))),  
  take(10)  
);  
powersOfTwo.subscribe(x => console.log(x));

In the code above, we have the of(1, 2, 3) Observable, which have the emitted values pipe d to the expand(x => of(x).pipe(delay(1000))) Observable. Then the first 10 values are taken from the Observable returned by expand, which takes the of(1, 2, 3) Observable’s emitted values and emit them repeatedly until we have 10 values emitted and each group is emitted after waiting 1 second.

This is because we specified of(x) which takes the of(1, 2, 3) values and then get then emit them without making any changes. pipe(delay(1000)) delays the emission of each group of values 1, 2 and 3 one second apart.

This should result in the following output:

1  
2  
3  
1  
2  
3  
1  
2  
3  
1

Conclusion

concatMapTo operator takes the source value of the Observable and maps each value to the same inner Observable.

The exhaust operator converts an Observable which emits Observables and then emit the values from the first inner Observable and discard the ones that haven’t finished emitting.

The exhaustMap operator also takes the first inner Observable then map them into inner Observables, which then have the values emitted.

Finally, the expand operator recursively projects each source value to an Observable which is then merged into the output Observable and emitted.

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.