Categories
JavaScript Tips

Useful JavaScript Tips — Variables and Arrays

Like any kind of apps, JavaScript apps also have to be written well.

Otherwise, we run into all kinds of issues later on.

In this article, we’ll look at some tips we should follow to write JavaScript code faster and better.

Assignment Operators

We can use compound assignment operators to make updating the values of numeric variables easier.

There are the += , -= , *= , /= , and %= operators which we can use to update numeric variables to whatever value we want based on the current one.

For instance, we can write:

x += 2;

Then we update the value of x by incrementing the current value by 2.

It’s the same as:

x = x + 2;

Likewise, we can do the same with the rest.

-= is subtraction.

*= is multiplication.

/= is for division.

And %= is for getting the remainder based on the current value.

So:

x %= 2;

is the same as:

x = x % 2;

Then we get the remainder of x divided by 2 based on the current value of x and reassigns it.

Converting Truthy or Falsy Values to Boolean

We can use the !! operator to convert anything to a boolean.

For instance, we can write:

!!""
!!0
!!null
!!undefined
!!NaN

They’re all falsy, so they all return false .

Other operands will return true . For instance, if we have:

!!"hi"

then that would return true .

Currying

Curry is the action of converting a function that takes multiple arguments into a series of functions that take a single argument.

It’s useful for creating functions that have some arguments applied and reuse that.

For instance, if we have an add function:

const add = (x, y) => {
  return x + y;
}

Then we can curry the function by writing:

const curriedAdd = (x) => {
  return (y) => {
    return x + y;
  }
}

Then we can call it by writing:

curriedAdd(1)(2)

and get 3.

Partial Application

We can partially apply arguments into a function by writing:

const plus10 = (y) => {
  return 10 + y;
}

Then we can write:

plus10(3);

Then we get 13.

To generalize this, we can write:

const partApply = (f, x) => {
  return (y) => {
    return f(x, y);
  }
}

Then we can call partApply by passing in a function for f and a value for x .

For instance, we can write:

const plus10 = partApply(add, 10);

Then we get 13 if we call plus10(3) since 10 is applied as the first argument.

Filtering and Sorting a List of Strings

We can sort filter strings with the filter method.

We can get the ones that we return an array that has words that have the same length as its index by writing:

const filtered = words
  .filter((word, index) => {
    return word.length > 2
  })

So if we have:

const words = ['do', 'if', 'foo', 'bar'];

Then we get:

["foo", "bar"]

Then we can call sort without any callback to sort strings since that’s how sort sorts array items without a callback.

So we can chain them by writing:

const filtered = words
  .filter((word, index) => {
    return word.length > 2
  })
  .sort();

Then we get [“bar”, “foo”] for filtered .

Using Immediately Invoked Function Expressions (IIFEs)

We can create and use IIFEs to enclose variables in a function so that they stay private.

For instance, we can write:

(() => {
  let x = 1;
  //...
})()

Then x stays inside the function.

This is one way to create private variables in a function.

Quick Way to Convert Numbers

To convert numbers easily, we can use the + operator to convert anything to a number.

For instance, we can write:

const one = +'1';

Then one is the number 1 instead of string '1' since we used the + operator on it.

Shuffle an Array

We can shuffle an array by using the sort method and return a random number that can be positive or negative so that we can shuffle them.

For instance, we can write:

const arr = [1, 2, 3];
arr.sort(() => -1 + (Math.random() * 2));

sort sorts an array in place, so we get a different value of it.

Returning -1 + (Math.random() * 2) will make the callback return something -1 and 1.

Conclusion

We can use various methods to filter and sort arrays.

Also, we can use assignment operators to make assignment statements shorter.

Categories
JavaScript Tips

Useful JavaScript Tips — Arrays, and Variables

Like any kind of apps, JavaScript apps also have to be written well.

Otherwise, we run into all kinds of issues later on.

In this article, we’ll look at some tips we should follow to write JavaScript code faster and better.

Assignment Operators

We can save some typing by using some compound assignment operators.

We can use the ++ and -- operators to increment and decrement by one respectively.

For instance, we can write:

a++

to increment a by 1.

Likewise, we can use:

++a

to do the same thing.

The only difference is whether it returns the later value or the old one.

We can do the same thing with -- , but decrements the value instead.

Ternary Operator

If we have:

const newValue;
if(value > 100) {
  newValue = 5;
} else {
  newValue = 2;
}

Then we can shorten it by writing:

const newValue = (`value > 100) ? 5 : 2;`

They do the same thing.

Null, Undefined, or Empty Checks

We can check for null , undefined and an empty string together by writing the following:

if (foo !== null || foo !== undefined || foo !== '') {
  const bar = foo;
}

We have to check null , undefined and empty string individually.

This is because empty string, null and undefined are different.

If we want to check other falsy values like 0 or NaN , then we can shorten it to:

const bar = foo || 'default';

Then when foo is any falsy value, then 'default' will be assigned to bar .

Array Literals

Instead of using the Array constructor:

const a = new Array();
a[0] = 'foo';
a[1] = 'bar';

We can write an array literal as follows:

const a = ['foo', 'bar'];

They do the same thing, but the array literal notation is much shorter.

Associative Array

We shouldn’t use the Array constructor for creating associative arrays.

Rather, we should create an object with dynamic keys.

For instance, we can write:

const skills = {
  'markup language' : 'HTML5',
  'programming language' : 'JavaScript'
};

We have 2 keys which aren’t valid identifiers.

But we can still use them since JavaScript objects can take string property names.

Asynchronous Loops

If we want to loop through setTimeout calls, then we can use let as follows:

for (let i = 0; i < 10; i++) {
  setTimeout(() => {
    console.log(i);
  }, 1000);
}

let is block-scoped, so the current value of i would be passed in.

Create an Array Sequence

We can create an array with a sequence of numbers starting from 0 with the Array constructor, fill , and map .

For instance, we can write:

const arr = Array(50).fill().map((_, i) => i);

We used the Array constructor to create an array with empty slots.

Then we called fill to fill the empty array with undefined .

This way, we can use map to map the entries by passing in a callback and return the index i of each entry.

Then we get an array between 0 and 50.

Ordering Object Properties

We can use the Object.keys method to return properties in an array.

Arrays are sortable so we can use that.

For instance, we can write:

Object.keys(obj)

and get the keys.

Also, we can use the Map constructor to create a map, which is traversed in insertion order.

For instance, we can write:

const map = new Map();
map.set('foo', 1);
map.set('@', 2);
map.set('bar', 3);
for (const [key, value] of map) {
  console.log(key, value);
}

Now we have Map instance that we can loop through keys in the same order that they’re inserted.

Avoiding Using Arguments

Don’t use the arguments object to get all the arguments.

Instead, we use the rest operator to get function arguments as an array.

For instance, we can write:

const foo = (...args) => {
  `for(const a of args) {
    //...
  }
}`

The ... is the rest operator which collects all the arguments in a function call and returns it as an array.

We can then call it by writing:

foo(1, 2, 3);

and args would be [1, 2, 3] .

Conclusion

We can use the rest operator to get the arguments from a function call.

The assignment operators are great. We can use the ++ and -- operators to increment and decrement our variables.

Also, we should use array literals as much as we can.

Categories
JavaScript Tips

Useful JavaScript Tips — Arrays and JSON

Like any kind of apps, JavaScript apps also have to be written well.

Otherwise, we run into all kinds of issues later on.

In this article, we’ll look at some tips we should follow to write JavaScript code faster and better.

Calculating the Average and Median

We can get the average by calculating the sum of the array and dividing that by the length of the array.

For instance, we can write:

const values = [2, 10, 28];
const sum = values.reduce((total, current) => current + total, 0);
const avg = sum / values.length;

We have the values array, which we get the sum of by using reduce .

Then we divide the returned sum by the length of values .

To get the median, we can sort the array, then get the average of the low and high middle value from the sorted array.

For instance, we can write:

const values = [2, 10, 28];
values.sort((a, b) => a - b);
const lowMiddle = Math.floor((values.length - 1) / 2);
const highMiddle = Math.ceil((values.length - 1) / 2);
const median = (values[lowMiddle] + values[highMiddle]) / 2;

We call sort to sort the array in ascending order by using the (a, b) => a — b callback.

Then we get the index of the low middle value by getting the floor of value ‘s length minus 1 divided by 2.

Likewise, we get the index of the high middle value by getting the ceiling of that.

Then we get the average of both values entries to get the median .

JSON.Stringify

We can turn objects into a string with JSON.stringify .

For instance, we can write:

const obj = {
  foo: `1`,
  bar: 2
};

const selectedProperties = ['foo'];

const str = JSON.stringify(obj, selectedProperties);

We have the obj object which we called stringify on with obj and select the properties with the second argument.

Then we get:

"{"foo":1}"

as the value of str .

We can also pass in a function:

const obj = {
  foo: 1,
  bar: 2
};

const selectedProperties = (key, val) => {
  if (!key || key === 'foo') {
    return val;
  }

  return;
}

const str = JSON.stringify(obj, selectedProperties);

We have a function that checks when to return val according to the given property.

Object.defineProperties

We can use Object.defineProperty to define a property to get more control over it.

For instance, we can write:

Object.defineProperty(obj, 'prop', {
  value: '123',
  enumerable: false,
  writable: false,
  configurable: false
});

We defined the prop property in obj value '123' , and all other properties set to false .

enumerable means whether we can see it from Object.keys or the for-in loop.

writable means whether we can change the value of it.

configurable means whether we can change the property descriptors.

Flattening Multidimensional Arrays

We can use the flat method to flatten multidimensional arrays.

For instance, we can write:

const arr = [[1, 2],[3, 4, 5]];
const flattened = arr.flat();

Then we get [1, 2, 3, 4, 5] for flattened .

We can also use concat to concatenate arrays.

For instance, we can write:

`const flattened` = [].concat.apply([], `arr`);

Also, we can use reduce to do the same thing:

const flattened = arr.reduce((flattened, curr) => flattened.concat(curr));

The spread operator can also do the same thing:

const arr = [[1, 2],[3, 4, 5]];
const flattened = arr.reduce((flattened, curr) => [...flattened, ...curr]);

That returns the arrays merged together.

We can also use the concat method with the spread operator:

const arr = [[1, 2],[3, 4, 5]];
const flattened = [].concat(...arr);

We spread the arr entries into arguments of the concat method.

Then concat appends the entries from the arrays.

Deduplicating an Array

We can remove duplicates from an array in several ways.

We can use the filter method to only return an array with the first instances of each entry by writing:

const deduped = [1, 1, 'b', 'b'].filter((el, i, arr) => arr.indexOf(el) === i);

We use the indexOf method, which returns the index of the first instance of entry to check whether it’s the first instance.

Also, we can convert it to a set to remove the duplicates and put spread it back into an array:

const deduped = Array.from(new Set([1, 1, 'b', 'b']));

or:

const deduped = [...new Set([1, 1, 'b', 'b'])];

Converting an array to a set removes the duplicates. Then we use Array.from or the spread operator to turn it back to a set.

Conclusion

We can use built-in methods and operations to calculate averages and medians.

Also, we can use them to remove duplicates.

We can also use them to flatten arrays.

JSON.stringify can take arguments to select which properties to stringify.

Categories
JavaScript Tips

JavaScript Tips — Good Constructs to Use

JavaScript is a very flexible language. There’s a lot of things in JavaScript that we probably shouldn’t write. Old constructs that aren’t good coexist with new constructures that are better.

In this article, we’ll look at some good parts of JavaScript that we should use regularly.

Don’t Use var, Use let or const

var is an outdated keyword for declaring variables. Instead, we should use let and const . let and const are both block-scoped, so that we can use them without worrying about clashing scopes as long as they’re in a block.

For instance, we can write the following:

let x = 1;
const y = 2;

instead of:

var x = 1;
var y = 2;

const also have the advantage that we can’t reassign a new value to it. However, it doesn’t make an object immutable.

Use === or Object.is Instead of ==

== saves one character of typing, but the rules for comparing with == is complex and hard to remember. It also produces lots of unexpected results. Therefore, we shouldn’t use == .

For instance, the following both return true :

[10]  == 10
'10' == 10

We probably don’t want that. Therefore, we should write the following instead:

[10] === 10
'10' === 10

Then they both return false since the data type and value of both operands have to match in order for the === to consider them the same. However, NaN === NaN returns false .

To check for NaN , we should use the isNaN function, which tries to convert its argument to a number and check against that. Therefore, isNaN(‘NaN’) and isNaN(NaN) both return true .

There’s also the Number.isNaN function, which doesn’t do any conversion when checking. Therefore, Number.isNaN(‘NaN’) returns false and Number.isNaN(NaN) returns true .

There’s also the Object.is method, which does the same thing as === ecept that NaN is the same as itself.

We can use that as follows:

Object.is('foo', 'bar')

The arguments are the 2 things that we want to compare.

undefined, null, 0, false, NaN, ‘’ (empty string) are all Falsy.

We have to remember these since they all return false when we try to convert them to boolean with !! or Boolean .

Use Semicolons for Line Termination

JavaScript is forgiving in that it doesn’t need semicolons for terminating lines. It’ll just insert the semicolons after line breaks or wherever it thinks it can end the line.

However, this will produce unexpected results. For instance:

const foo = () => {
  return
  {
    first: 'john'
  };
}

will return undefined because the semicolon is added after return , so the code below it is never run.

Therefore, we should insert semicolons as needed to clarify where a line ends.

Use Class Syntax for Object Constructors

In JavaScript, classes are the same as object constructore functions. However, the syntax is stricter so that it’s harder to make mistakes, especially when we need to do inheritance. For instance, we can write the following class:

class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }
}

which is the same as:

function Person(firstName, lastName){
  this.firstName =  firstName;
  this.lastName = lastName;
}

It’s just that the class syntax is more conventional syntax, especially for people who worked with other object-oriented languages.

It makes even more sense if we have methods. For instance, with the class syntax, we write:

class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  fullName() {
    return `${this.firstName } ${this.lastName }`;
  }
}

The Person class above has the fullName method. On the other hand, with the old constructor function syntax, we write:

function Person(firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;
}

Person.prototype.fullName = function() {
  return `${this.firstName } ${this.lastName }`;
}

This just doesn’t make as much sense for many developers, especially for non-JavaScript developers.

The class syntax makes things much clearer. The class syntax makes even more sense with inheritance. With the old syntax, we write:

function Person(firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;
}

Person.prototype.fullName = function() {
  return `${this.firstName } ${this.lastName }`;
}

function Student(studentId) {
  Person.call(this, studentId);
}
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Person;

There’re no errors if we missed anything when we write the code above.

However, with the class syntax, we write:

class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }
  fullName() {
    return `${this.firstName } ${this.lastName }`;
  }
}

class Student extends Person {
  constructor(firstName, lastName, studentId) {
    super(firstName, lastName);
    this.studentId = studentId;
  }
}

We’ll also get errors if we didn’t follow the syntax like forgetting to call super when we have extends .

Conclusion

There’re a few important things we should use to write JavaScript code, including === instead of == , class syntax instead of constructor functions and prototype, use let and const instead of var to declare variables and constants, and remember falsy values

Categories
Nodejs

How to Dockerize a Node Web App

Running our Node web app in Docker saves us lots of headaches.

Every time a Docker image is deployed, it’s guaranteed to deploy a fresh container.

This way, we won’t have to worry about messing up our code in the container.

Also, the Docker image is built with an image, so we can build it repeatedly without doing anything manually.

In this article, we’ll look at how to Dockerize a simple Node web app.

Create the Node.js App

We start by creating our Node app.

To start, we create a project folder and run npm init --yes to create package.json .

Then we can replace everything in their with:

{
  "name": "my-app",
  "version": "1.0.0",
  "description": "a simple app",
  "author": "",
  "main": "server.js",
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {
    "express": "^4.16.1"
  }
}

Then we create a server.js file in the same folder and add:

'use strict';

const express = require('express');

const PORT = 8080;
const HOST = '0.0.0.0';

const app = express();
app.get('/', (req, res) => {
  res.send('Hello World');
});

app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`);

It just has one route that responds with ‘hello world’.

Creating a Dockerfile

Next, we create a Dockerfile in the project folder.

Then we add:

FROM node:12
WORKDIR /usr/src/app
COPY package*.json ./

RUN npm install
COPY . .

EXPOSE 8080
CMD [ "node", "server.js" ]

We get the Node 12 image, then create a working directory to build the image.

Then we copy package.json and package-lock.json to the root directory with COPY package*.json ./

Next, we run npm install to install the packages.

And then we bundle the app’s source code with COPY . . .

Then we use EXPOSE 8080 to open the 8080 port for the Docker image.

Finally, we run node server.js to start the app with CMD [ “node”, “server.js” ] .

Next, we create .dockerignore file to stop Docker from copying the local modules to the Docker container.

We do the same with the NPM logs.

So we have the following in .dockerignore :

node_modules
npm-debug.log

Building the Image

We can then build the image with:

docker build -t <your username>/my-app .

Where <your username> is the username of your account.

Then we should see our image when we run docker images .

Run the Image

Once it’s built, we can run our image with:

docker run -p 8888:8080 -d <your username>/my-app

-d runs the container in detached mode, which leaves it running in the background.

-p redirects a public port to a private port in the container.

We can then run docker ps to get the container ID.

The app’s output can be obtained with:

docker logs <container id>

And we can go into the container with:

docker exec -it <container id> /bin/bash

Then to test our app, we can run:

curl -i localhost:8888

Then we should get the ‘hello world’ response from the app.

Conclusion

We can create a Docker image for a Node web app with a simple Dockerfile.

Then we don’t have to do much to get it running with Docker.