Categories
JavaScript JavaScript Best Practices

Removing Useless Expressions – JavaScript Best Practices

To make code easy to read and maintain, we should follow some best practices.

In this article, we’ll look at some best practices we should follow to make everyone’s lives easier.

No Constant Expressions in Conditions

We shouldn’t have constant expressions in conditions.

They either always run or never run if they’re present.

For instance, don’t write:

if (false) {
   foo();
}

Instead, write:

if (x === 1) {
   foo();
}

No Control Characters in Regex

We shouldn’t have control characters in a regex.

They are rarely used and it’s probably a mistake to check for them.

Instead of writing:

const pattern = /\x1f/;

or:

const pattern = new RegExp("\x1f");

We write:

const pattern1 = /\x20/;
const pattern2 = new RegExp("\x20");

instead.

Don’t Use debugger

debugger sets a breakpoint in our JavaScript code so we can inspect the variables.

This shouldn’t be in our production code.

So instead of writing:

const isTruthy = (x) => {
  debugger;
  return Boolean(x);
}

We write:

const isTruthy = (x) => {
  return Boolean(x);
}

No Duplicate Arguments in Function Definitions

Duplicate argument names isn’t valid syntax.

It’ll throw an error if strict mode is on.

Instead of writing:

function foo(a, b, a) {
  console.log(a);
}

We write:

function foo(a, b) {
  console.log(a);
}

No Duplicate if-else-if Conditions

We shouldn’t have duplicate conditions in our if statements.

The duplicate is useless and causes confusion.

So instead of writing:

if (isSomething(x)) {
  foo();
} else if (isSomething(x)) {
  bar();
}

We write:

if (isSomething(x)) {
  foo();
}

No Duplicate Keys in Object Literals

Duplicate keys are confusing and useless.

So we shouldn’t write:

const foo = {
   bar: "baz",
   bar: "qux"
};

Instead, we write:

const foo = {
   bar: "qux"
};

No Duplicate case Label

switch statements shouldn’t have more than one case label.

As with other duplicates, they cause confusion and are redundant.

So instead of writing:

switch (a) {
  case 1:
    break;
  case 2:
    break;
  case 1:
    break;
  default:
    break;
}

We write:

switch (a) {
  case 1:
    break;
  case 2:
    break;
  default:
    break;
}

No Empty Block Statements

Empty blocks are useless. So we should remove them.

Instead of writing:

if (foo) {
}

or

while (foo) {
}

or

switch(foo) {
}

We write:

if (foo) {
  bar();
}

or

while (foo) {
  bar();
}

or:

switch(foo) {
  case 1:
    //...
    break;
}

Conclusion

We shouldn’t have duplicates of most things.

Also, we should remove control characters from regexes and debugger.

Categories
JavaScript JavaScript Best Practices

Basic JavaScript Best Practices

To make code easy to read and maintain, we should follow some best practices.

In this article, we’ll look at some best practices we should follow to make everyone’s lives easier.

Having the Correct for Loop Direction

We should make sure that we update the index variable in the right direction so that we don’t get infinite loops.

For instance, the following is probably wrong:

for (var i = 0; i < 10; i--) {
}

The loop never ends since i is being decremented in each iteration.

Instead, we should write:

for (var i = 0; i < 10; i++) {
}

so that the i variable gets to 10.

Return Statement should be Present in Property getters

If we define a getter, then we should return something.

Otherwise, the getter is useless.

For instance, instead of writing:

const obj = {
  get name() {
    
  }
};

We write:

const obj = {
  get name() {
    return 'james'  
  }
};

or:

 Object.defineProperty(person, "age", {
   get() {
     return 17;
   }
 });

No async Function as a Promise Executor

We shouldn’t have async functions in our Promise constructor.

This is because async functions already returns promises, so it’s redundant.

For instance, we shouldn’t write;

const result = new Promise(async (resolve, reject) => {
  resolve(await foo);
});

or:

const foo = new Promise(async (resolve, reject) => {
  readFile('bar.txt', (err, result) => {
    if (err) {
      reject(err);
    } else {
      resolve(result);
    }
  });
});

It’s completely redundant to have them.

Instead, we write:

const foo = new Promise((resolve, reject) => {
  readFile('bar.txt', (err, result) => {
    if (err) {
      reject(err);
    } else {
      resolve(result);
    }
  });
});

or:

const result = Promise.resolve(1);

No await Inside Loops

We should move await outside of promises that can run in parallel.

So instead of writing:

copnst foo = async (things) => {
  const results = [];
  for (const thing of things) {
    results.push(await bar(thing));
  }
  return baz(results);
}

We write:

const foo = async (things) => {
  const results = things.map(thing =>bar(thing));
  return baz(await Promise.all(results));
}

We map the things entries to promises.

Then we use Promise.all to run all the promises in parallel.

No Comparison Against -0

Comparing against -0 won’t work as intended.

Instead, we compare an expression with 0.

So instead of writing:

if (x === -0) {
  //...
}

We write:

if (x === 0) {
  //...
}

We can use Object.is to compare against -0:

if (Object.is(x, -0)) {
  // ...
}

Object.is distinguishes between +0 and -0.

No Assignment Operators in Conditional Statements

Assinging things in operators is probably a mistake if we don’t compare it against something.

For instance:

if (user.title = "employee") {
  //...
}

isn’t comparing user.title to 'employee'.

Instead, we write:

if (x === 0) {
   b = 1;
}

to make sure we’re comparing against an expression.

Remove console from Production Code

We shouldn’t run console.log when our code goes to production.

Therefore, we should remove them.

It’s good for debugging but we should remove them before we check in our code.

Conclusion

We should take note of some basic best practices when writing JavaScript code.

Don’t use async and await with the Promise constructor.

Don’t write infinite loops unintentionally.

And return things in getters.

Also, don’t assign variables unintentionally in our if statements.

Categories
JavaScript Vue

Vue Components — Dynamic and Async Components

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 dynamic and async components.

keep-alive with Dynamic Components

We sometimes want to maintain the state or avoid re-rendering for performance reasons when we switch between components dynamically.

For example, we can use it as follows to keep the states of components when switching between them:

src/index.html :

Vue.component("post", {  
  data() {  
    return {  
      showDetails: false  
    };  
  },  
  template: `  
    <div>  
      <h1>Title</h1>  
      <button @click='showDetails = !showDetails'>  
        Toggle Details  
      </button>  
      <div v-if='showDetails'>  
        Lorem ipsum dolor sit amet.  
      </div>  
    </div>  
  `  
});

Vue.component("archive", {  
  data() {  
    return {  
      showDetails: false  
    };  
  },  
  template: `  
    <div>  
      <h1>Archive</h1>  
    </div>  
  `  
});

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

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">  
      <button @click'tabName = "post"'>Post</button>  
      <button @click='tabName = "archive"'>Archive</button>  
      <keep-alive>  
        <component v-bind:is="tabName"></component>  
      </keep-alive>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>

Then when we click Toggle Detail to show the text in the Post tab, we’ll see that it’ll still be shown after switching to the Archive tab and back.

This is because we wrapped keep-alive around our component element.

keep-alive requires that the components being switched between to all have names.

Async Components

We can create components that are loaded from the server only when it’s needed with async components.

To do this, instead of passing in an object as the second argument, we pass in a function that returns a promise instead. For example, we can write the following:

src/index.js :

Vue.component("async-component", (resolve, reject) => {  
  setTimeout(() => {  
    resolve({  
      template: "<div>Async component</div>"  
    });  
  }, 1000);  
});

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

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">  
      <async-component></async-component>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>

Then we should see ‘Async component’ shown on the screen after 1 second.

We see that the function above takes a resolve function from the parameter and calls it when we want to retrieve the definition from the server.

To indicate loading has failed, we can call reject(reason) to do that.

Another example would be using it with Webpack code-splitting as follows:

Vue.component('async-webpack', function (resolve) {  
  require(['./async-component'], resolve)  
})

We can also use the import function to import a component as follows:

Vue.component(  
  'async-webpack',  
  () => import('./async-component')  
)

If we want to register a component locally, we can write:

new Vue({  
  // ...  
  components: {  
    'component': () => import('./async-component')  
  }  
})

Handling Loading State

We can return a promise that has an object to referencing components for loading and error.

For example, we can use it with an app that’s generated by the Vue CLI by running npx vue create app where app is the app name. Then we can select the default choices within the wizard.

Then we write the code as follows:

App.vue :

<template>  
  <div id="app">  
    <AsyncComponent/>  
  </div>  
</template>

<script>  
import Loading from "./components/Loading";  
import Error from "./components/Error";  
import HelloWord from "./components/HelloWorld";

const AsyncComponent = () => ({  
  component: new Promise(resolve => {  
    setTimeout(() => {  
      resolve(HelloWord);  
    }, 1000);  
  }),  
  loading: Loading,  
  error: Error,  
  delay: 0,  
  timeout: 3000  
});

export default {  
  name: "App",  
  components: {  
    AsyncComponent  
  }  
};  
</script>

<style>  
</style>

components/HelloWorld.vue :

<template>  
  <div>Hello</div>  
</template>

components/Error.vue :

<template>  
  <div>Error</div>  
</template>

component/Loading.vue :

<template>  
  <div>Loading</div>  
</template>

In App.vue , the following code:

component: new Promise(resolve => {  
    setTimeout(() => {  
      resolve(HelloWord);  
    }, 1000);  
  })

delays loading of the HelloWorld component for a second. delay is the number of milliseconds before the loading component is shown.

timeout is the number of milliseconds until Vue stops trying to load the component.

Therefore, we’ll see Loading from the Loading component as the HelloWorld component is loading.

This kind of component definition is available since Vue 2.3.0. Vue Router 2.4.0 should be used if we want to use the above syntax for route components.

Conclusion

We can use keep-alive to keep the current state of the component as it’s being rendered dynamically with the component element.

We can define async components with Vue.component by passing in a function that returns a promise.

In Vue 2.3.0 or later, we can define an async component by creating a function that returns an object that has the promise that resolves to the component as the component that’s rendered.

We can also specify the Loading and Error components in addition to the delay for loading the Loading component and timeout until Vue stops trying to load the component.

Categories
Express JavaScript Nodejs

Tracking Response Time of Express App Responses

To gauge the performance of our apps, we need to measure the response time of our API.

To do this with our Express app, we can use the response-time package.

Installation

response-time is available as a Node package. We can install it by running:

npm install response-time

Then we can import it by writing:

const responseTime = require('response-time');

responseTime([options])

We can set various options by passing an object into the optional options parameter.

It’ll create a middleware that adds a X-Response-Time header to responses.

The options object takes the following properties:

digits

The digits property is a fixed number of digits to include in the output, which is always in milliseconds. The default is 3.

header

The name of the header to be set. It defaults to X-Response-Time.

suffix

The suffix property is a boolean property to indicate if units of measure should be added to the output. The default value is true.

responseTime(fn)

The function creates a middleware that records the response time of a request and makes it available to our own function fn. fn has the signature (req, res, time) where time is a number in milliseconds.

Examples

Simple Example

We can use the responseTime package without any options or function passed in:

const express = require('express');  
const bodyParser = require('body-parser');  
const responseTime = require('response-time')  
const app = express();  
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));

app.use(responseTime());

app.get('/', (req, res) => {  
  res.send('foo');  
});

app.listen(3000);

Then we get a X-Response-Time response header with a value like 0.587ms.

We can check the response header on an HTTP client like Postman.

Passing in Options

We can change the options for the header returned with the response. For example, we can write the following to change the number of digits sent:

const express = require('express');  
const bodyParser = require('body-parser');  
const responseTime = require('response-time')  
const app = express();  
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));

app.use(responseTime({  
  digits: 5  
}))

app.get('/', (req, res) => {  
  req.id = 1;  
  res.send('foo');  
});

app.listen(3000);

Then we get a X-Response-Time response header with a value like 0.71987ms.

Passing in Our Own Function

We can pass a function into the responseTime function as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const responseTime = require('response-time')  
const app = express();  
app.use(bodyParser.json());  
app.use(bodyParser.urlencoded({ extended: true }));

app.use(responseTime((req, res, time) => {  
  console.log(`${req.method} ${req.url} ${time}`);  
}))

app.get('/', (req, res) => {  
  req.id = 1;  
  res.send('foo');  
});

app.listen(3000);

Then we get something like:

GET / 2.9935419999999997

from the console.log.

It’s useful if we want to manipulate the response time data or log it ourselves.

Conclusion

We can get the response time in the response header of a request with the response-time package.

It has a responseTime function which returns a middleware that we can use with the use method of express or express.Router() .

The function can either take an options object and or a function with the req, res, and time parameters to get the request, response, and response time respectively.

Categories
JavaScript Vue

Event Handling in Vue.js Components

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 handle events in Vue components, including how to use v-model with custom components and passing data between parent and child.

Listening to Child Components Events

We can send events from a child component to the parent to run code in the parent component.

For example, if we want to add a button to each post to change the font of the page, we can do that as follows:

src/index.js :

Vue.component("post", {  
  props: ["post"],  
  template: `  
    <div>  
      <h2>{{post.title}}</h2>  
      <div>{{post.content}}</div>  
      <button v-on:click="$emit('change-font')">  
        Change Font  
      </button>  
    </div>  
  `  
});

new Vue({  
  el: "#app",  
  data: {  
    posts: [{ title: "Foo", content: "foo" }, { title: "Bar", content: "bar" }],  
    font: ""  
  },  
  methods: {  
    changeFont() {  
      this.font = this.font === "" ? "courier" : "";  
    }  
  }  
});

We added the changeFont method to let us change the font in the Vue app. This will be called when the change-font event is emitted from the post component.

The change-font event is emitted from post when the Change Font button is clicked.

The event is emitted with the $emit method. The string we passed in is the name of the event.

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">  
      <div v-bind:style="{'font-family': font}">  
        <post  
          v-for="post in posts"  
          v-bind:post="post"  
          v-on:change-font="changeFont"  
        ></post>  
      </div>  
    </div> <script src="src/index.js"></script>  
  </body>  
</html>

In the template, we have the v-bind:style attribute to set the font of the div dynamically with v-bind:style=”{‘font-family’: font}”.

When the change-font event is received, then the changeFont method will be called to toggle the font between Courier and the default.

The $emit method also takes a second argument with the value that we want to send back to the parent.

For example, we can rewrite the font change code as follows:

src/index.js :

Vue.component("post", {  
  props: ["post"],  
  template: `  
    <div>  
      <h2>{{post.title}}</h2>  
      <div>{{post.content}}</div>  
      <button v-on:click="$emit('change-font', 'courier')">  
        Change Font  
      </button>  
    </div>  
  `  
});

new Vue({  
  el: "#app",  
  data: {  
    posts: [{ title: "Foo", content: "foo" }, { title: "Bar", content: "bar" }],  
    font: ""  
  },  
  methods: {  
    changeFont(font) {  
      this.font = this.font === font ? "" : font;  
    }  
  }  
});

In the code above, we passed in 'courier' to the $emit function. The item in the second argument will be available as the $event in the parent 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">  
      <div v-bind:style="{'font-family': font}">  
        <post  
          v-for="post in posts"  
          v-bind:post="post"  
          v-on:change-font="changeFont($event)"  
        ></post>  
      </div>  
    </div> <script src="src/index.js"></script>  
  </body>  
</html>

In the template, we pass in $template , which contains 'courier' to the changeFont method.

The changeFont method toggles the font between the font that we passed in as the argument and an empty string.

So it does the same thing as before.

This lets us pass data from a child component to a parent component.

Using v-model on Components

v-model is the same as the v-bind:value and v-on:input together. This means that:

<input v-model="text">

is the same as:

<input v-bind:value="text" v-on:input="text= $event.target.value" >

Since components take props and emit events, we can combine the value propr and the input event binding into the v-model directive.

For example, we can use it to make our own custom input as follows:

src/index.js :

Vue.component("styled-input", {  
  props: ["value"],  
  template: `  
    <input  
      v-bind:style="{'font-family':'courier'}"  
      v-bind:value="value"  
      v-on:input="$emit('input', $event.target.value)"  
    >  
  `  
});

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

In the code above, we created the style-input component to change the font of the input to Courier.

Also, we use v-bind:value to get the value of the value prop and emit the input event as the text is inputted into the input box.

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">  
      <styled-input v-model="text"></styled-input>  
      <br />  
      {{text}}  
    </div> <script src="src/index.js"></script>  
  </body>  
</html>

In the code above, we can use v-model to bind to the text data field since v-model is the same as combining v-bind:value with v-on:input .

styled-input emitted the input event and takes the value prop, so we can merge them together into v-model .

Conclusion

We can emit events with the $emit from a child component to the parent. It takes 2 arguments. The first argument is the string for the event name, and the second argument is the object that we want to pass to the parent.

The parent can access the object passed from the child by listening to the event with the v-on directive and then retrieve them item pass from the child with the $event object.

v-bind:value and v-on:input is the same as v-model , so v-bind:value and v-on:input can be combined into one and v-model can be used with custom components.

This lets us create custom inputs easily.