Git Hooks Made Easy – Husky

Git hooks are custom scripts that you can drop inside your .git directory which are executed at a specified point in time. These scripts are usually executed after a certain event is occurred or about to occur. For example, we can have a script i.e. executed before commit or after the commit has happened. These scripts can be used to perform automated tasks such as executing all the test cases before pushing the changes to the git or sending an email notification to all the members when a user pushes the changes to git.

The Problem!

The git hooks are located inside the .git/hooks directory. The problem with hooks is you cannot commit and push your hooks and share it with your team members since the .git folder is not versioned.

Husky to the rescue!

To install husky in your project all you need to do is open your terminal and type following npm command.

npm install --save-dev husky

You could also use yarn to install this package.

yarn add husky --dev

Now, to add new hooks to you’re project open your package.json file.

{
  "husky": {
    "hooks": {
      "pre-commit": "npm run lint",
      "pre-push": "npm test",
      "...": "..."
    }
  }
}

In the above example, we’re using to hooks first executes linting before committing the changes and second runs all your tests before pushing the changes to the repository. If any of the npm scripts fails the git action following the script won’t be executed. You are free to replace npm run lint or npm test with your own npm scrips.

You can also run more then one script in your hook using the &&. For example npm run lint && npm test.

For more Information:

  1. https://git-scm.com/docs/githooks
  2. https://github.com/typicode/husky

Must Read: Angular Meta Service for Meta Tags

Object.freeze() vs const

In this post, we’re going to explore the difference between const keyword and the Object.freeze method and understand how we could utilize these features to gain better control over our object properties.

const

The const keyword was introduced with ES6 as a way to create constant variables in JavaScript. It is used to create an immutable binding i.e. you cannot re-assign a new value to a variable created using const keyword.

const person = { name: 'Harshal' }
person = { name: 'John' } // Uncaught TypeError: Assignment to constant variable.

The above code will trigger error as we’re trying to assign a new value to person variable.

However, one point we need to understand is const keyword makes the binding of the variable immutable, not the value itself. Let’s understand this using an example.

const person = { name: 'Harshal' }
person.name = 'John';
console.log(person.name); // John

As you can see in the above example, we can change the value of the property name on the object person even after being assigned.

Object.freeze

Object.freeze is used to freeze an object. Once an object is frozen no value modifications are allowed on that object. Let’s understand this in detail using a code sample.

let person = Object.freeze({ name: 'Harshal' });
person.name = 'John';
console.log(person.name) // Harshal

As you can see in the above code, although we’re modifying the value of name property it is simply ignoring all the modifications and simply holding on to the value used while freezing the object.

One important thing to note is the Object.freeze method makes the object immutable not the binding i.e it is possible to re-assign a new value to a frozen variable.

let person = Object.freeze({ name: 'Harshal' });
person.name = 'John';
console.log(person.name); // Harshal

person = Object.freeze({ name: 'John' });
console.log(person.name); // John

As you can see in the above code, we’re not able to modify the value the person but we can assign a new value to the object.

Must Read: Angular Meta Service for Meta Tags

Conclusion

The const keyword creates immutable bindings i.e you cannot assign a new value to a variable once it is created however you can modify the existing values of the constant.

The Object.freeze method creates immutable object i.e. it’ll not allow you to modify, create or delete properties of a frozen object but it doesn’t prevent you from assigning a new value to the object.

How to Disable Theme and Plugin Editor from WordPress Admin Panel

WordPress comes bundled with a code editor which allows you to edit your theme and plugin files from your Dashboard. To access theme editor you need to navigate to Appearance > Editor and to access plugin editor you need to navigate to Plugins > Editor.

Although this feature comes in handy, it can lead to serious issues like source code modifications by someone with the admin access who is not familiar to programming, leading to the website crash or malware installation by a malicious user who somehow managed to gain admin access.

You can easily avoid these issues by disabling the theme and plugin editor from the dashboard. All you need to do is open your wp-config.php file located inside your root directory. And drop the following code before the line that contains /* That’s all, stop editing! Happy blogging. */ comment.

define( 'DISALLOW_FILE_EDIT', true );

And that’s it! This will remove both theme and plugin editor from your WordPress dashboard.

Quick Tip: How to Remove URL / Website Field from WordPress Comment Form

Angular Meta Service for HTML Meta Tags

HTML meta tags are used to provide metadata about the HTML web page such as page description, author name, important keywords or other metadata. Meta tags play an important role in search engine optimization.

Angular comes bundled with Meta service which allows us to deal with these HTML meta tags. In this post, we’re going to understand how we can leverage various methods available within this service to manage the meta tags more efficiently.

Usage

To use this service first you need to import it from @angular/platform-browser.

import { Meta } from '@angular/platform-browser';

Once the service is imported you need to inject it inside your component via the constructor like any other service.

constructor(private meta: Meta) {

}

Adding Meta Tags

Meta service comes bundled with two methods which allow you to add meta tags to your web page i.e. addTag and addTags.

addTag method accepts only a single object at once and generates only one meta tag.

import { Component } from '@angular/core';
import { Meta } from '@angular/platform-browser';

@Component({
  selector: 'app-main',
  templateUrl: './main.component.html',
  styleUrls: ['./main.component.scss']
})
export class MainComponent {
  constructor(private meta: Meta) {
    this.meta.addTag({ name: 'author', content: 'Harshal Limaye' });
  }
}

If you wish to create multiple tags using addTag you need invoke it multiple times.

constructor(private meta: Meta) {
  this.meta.addTag({ name: 'author', content: 'Harshal Limaye' });
  this.meta.addTag({ name: 'description', content: 'Front-end developer' });
}

You could use addTags method to set multiple tags in a single call. This method accepts array of objects that describes the meta tags.

constructor(private meta: Meta) {
  this.meta.addTags([
    { name: 'author', content: 'Harshal Limaye' },
    { name: 'description', content: 'Front-end developer' }
  ]);
}

Note: You could pass a second parameter as a boolean value to both addTag or addTags methods to determine if tag needs to be added even if it already exists. The default value is false.

this.meta.addTag({name: 'author', content: 'Harshal Limaye'}, true);

Retrieving Meta Tags

You can use getTag and getTags methods to retrieve the values of existing meta tags. the getTag method returns a single element whereas the getTags method returns an array of the element.

constructor(private meta: Meta) {
  const author: HTMLMetaElement = this.meta.getTag('name=author');
  console.log(author.content); // Harshal Limaye
}

If no meta tag is found for specified selector method returns null.

Updating Meta Tags

updateTag method could be used to update the value of a HTML meta tag.

constructor(private meta: Meta) {
  this.meta.updateTag({name: 'keywords', content: 'Angular, React, Vue, D3'});
}

The above code will update the value of keywords meta tag to “Angular, React, Vue, D3”

Removing Meta Tags

removeTag method could be used to remove existing HTML meta tags.

constructor(private meta: Meta) {
  this.meta.removeTag('name=author');
}

The above code removes author meta tag from the web page.

removeTagElement method could also be used to remove a meta tag. Unlike removeTag which accepts attribute selector it accepts HTMLTagElement as a parameter.

constructor(private meta: Meta) {
  const author: HTMLMetaElement = this.meta.getTag('name=author');
  this.meta.removeTagElement(author);
}

Conclusion

The Angular Meta service allows us to add, retrieve, update and remove HTML meta tags from the web page. This could be very helpful to dynamically update meta tags based on the currently active route in your application.

Must Read: Using Custom Pipes in a Component Class in Angular

Maximize The Browser Window Using Protractor

Protractor is browser automation and end-to-end testing framework built on-top of JavaScript Selenium webdriver for testing Angular based applications. It tests your applications like a real user by running your tests using the real web browsers.

In this post, we’re going to learn to maximize the browser window while running the automation tests.

Protractor comes bundled with feature which allows you to do the same

browser.driver.manage().window().maximize();

To maximize your window all you need to do is use above code inside your tests.

describe('testing super calc using protractor', function() {
  it('should maximize the web browser window', function() {
	browser.driver.manage().window().maximize();
	browser.driver.get('https://juliemr.github.io/protractor-demo/');
  });
});

If you wish to run all your tests in maximized window, you can take advantage of onPrepare method inside your configuration file.

exports.config = {
  seleniumAddress: 'http://localhost:4444/wd/hub',
  specs: ['*.spec.js'],
  onPrepare: function() {
    browser.driver.manage().window().maximize();
  }
};

And that’s it! In case if you’ve any query or feedback feel free to drop a comment.

Recommended: How to Run Protractor Test Cases in Firefox Browser

How to Run Protractor Test Cases in Firefox Browser

Here’s a quick tip on how to run your Protractor end-to-end test cases using Firefox web browser.

To use Protractor with Firefox all you need to do is you need to specify browser name inside your Protractor configuration file within the capabilities object.

capabilities: {
    'browserName': 'firefox'
}

And that’s it. If you’ve any query or feedback feel free to drop a comment.

Must Read: Managing Node.js Versions with NVM

Using Custom Pipes inside an Angular Component Class

In this tutorial, we’re going to learn to use Angular Pipes inside a component class. In one of my previous tutorials, we’ve created a custom pipe that accepts a number and returns its square. For this tutorial we’re going to inject that pipe inside a component

Before you can use your pipe inside a component class you need to add it to providers array of your module.

providers: [SquarePipe,...]

Next thing you need to do is you need to inject the pipe as service in the constructor of your component class.

// ...
import { SquarePipe } from './square.pipe';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {

  constructor(
    private square: SquarePipe
  ) { }

  // ...
}

And, To use this pipe you need to simply utilise the transform method on the instance of pipe object injected in the class.

getSquare(val): void {
  this.squareVal = this.square.transform(val);
  // ...
}

And that’s it. In case, you’ve any query or feedback feel free to drop a comment.

Method Chaining in TypeScript

In this post, we’re going to implement method chaining pattern using TypeScript.

What is method chaining?

Method chaining is a pattern which allows the developers to invoke multiple methods on the same instance of object. When used efficiently, this pattern makes the code a lot more readable.

If you write JavaScript for living, chances are you’ve already used method chaining in one way or another.

Here’s an example of method chaining in jQuery.

$("#card")
  .css('background', 'red')
  .width(400)
  .text('hello world!');

Implementing method chaining

Let’s start by building a Calculator class

class Calculator {
    private _value: number;
 
    constructor(value: number) {
        this._value = value;
    }
 
    add(num: number): Calculator {
        this._value = this._value + num;
        return this; 
    }
    subtract(num: number): Calculator {
        this._value = this._value - num;
        return this;
    }
    multiply(num: number): Calculator {
        this._value = this._value * num;
        return this;
    }
    divide(num: number): Calculator {
        this._value = this._value / num;
        return this;
    }
    result(): number {
        return this._value;
    }
}

As you can see, each method on the class returns this i.e the current instance of the object.

Now, lets create an object using out Calculator class and call it’s methods.

const calc = new Calculator(10);
console.log(
    calc.add(10)
        .multiply(5)
        .divide(10)
        .subtract(4)
        .result()
);

The above code will output 6 in the console.

That’s it! I hope you liked this post. If you’ve any query or feedback, feel free to drop a comment.

Set default node version with NVM

NVM or the Node version manager is a tiny command line application which enables you to efficiently manage multiple versions of node on your computer.

In this quick post, we’ll learn to set the default version of node using NVM.

To set the default node version use the following command. Make sure you replace 10.15.0 with your desired version.

nvm alias default 10.15.0

If you encounter an error similar to something as shown below, the version you’re trying to use might not be installed on your computer.

! WARNING: Version '10.15.0' does not exist.
default -> 10.15.0 (-> N/A)

Use the following command to install the missing node version and then try to set it as the default version.

nvm install 10.15.0

To make sure if NVM has set the desired node version as default use the following command.

node -v

If everything went well you’ll see the following output in your terminal window.

v10.15.0

Must Read: LocalStorage in JavaScript

Custom Pipes – Angular

Pipes are used for transforming or formatting your data from within your templates. Angular comes bundled with a large number of built-in pipes including uppercase, lowercase, date, currency, and percent. However, there is a good chance that you might run into scenarios where you’ll need to create your own custom pipes.

In this post, we’re going to create our own custom pipe. We’re going to build pipe which accepts a number and returns it’s square. We’ll start by creating a new Typescript file ‘square.pipe.ts’.

Next thing we’ll do is import Pipe decorator and PipeTransform interface at the top of that file.

import { Pipe, PipeTransform } from '@angular/core';

Next, we’ll create a class SquarePipe which implements the PipeTransform interface and we’ll decorate it with Pipe decorator.

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'square'
})
export class SquarePipe implements PipeTransform {
 
}

The value of name property is used to refer to the pipe inside the template.

Now, we’ll create a method called transform which accepts the value that needs to be processed and returns it’s square.

transform (value: number): number {
    if (isNaN(value)) {
      return value;
    }

    return value * value;
  }

The if condition determines if the value to be processed is a number. If not we’ll return the original value.

The final code is as follows:

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'square'
})
export class SquarePipe implements PipeTransform {
  transform (value: number): number {
    if (isNaN(value)) {
      return value;
    }

    return value * value;
  }
}

Before using the pipe, we need to make our Angular app aware of the pipe. We can do that by adding pipe to our declarations array in the module.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { SquarePipe } from './square.pipe';

@NgModule({
  declarations: [
    AppComponent,
    SquarePipe
  ],
  imports: [
    BrowserModule,
    FormsModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [ AppComponent ]
})
export class AppModule { }

You can use our custom pipe in following way.

{{ num | square }}

Passing arguments to the pipe

You can also pass parameters to your pipe. For example, we’re passing city name as parameter to greeter pipe.

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'greeter'
})
export class GreeterPipe implements PipeTransform {
  transform (value: string, city: string): string {

    return `Hello ${value}! Welcome to ${city}.`
  }
}

You can use the above pipe in following way.

{{ 'John' | greeter : 'Pune' }}

The above code will produce following output.

Hello John! Welcome to Pune.

I hope you found this post about Angular Pipes useful. If you have any query or feedback feel free to drop a comment.

Useful Read: Inject Document In Angular