What is Latest Features of Angular.js?

What is Latest Features of Angular.js?

In this post, we discuss the latest features in Angular.js, including differential loading. Go in-depth on what's new in Angular.

The latest version of Angular was slated to release in March-April 2019. But, it eventually happened in 2019. Yes, we are talking about Angular 8 — the latest version of Angular.js.

However, Angular 7.0 is supported until April 2022. So, it becomes imperative for organizations to explore the new features incorporated in Angular 8 and decide on embracing Angular 8 whether or not they should upgrade from Angular 7.0.

New Features of Angular 8.0

Differential Loading of JavaScript

Differential loading enables browsers to select optimized or legacy bundles according to their capabilities and then automatically load the correct one. Users then receive the bundle(s) they require based on their specific needs.

In the latest version, Angular serves different browsers with different bundles, and this is by default. The CLI extensions generate different bundles for old legacy ES5 browsers and modern JavaScript (ES2015+) browsers.

Moreover, it enhances the loading speed and the time to interactive (TTI) for a modern browser. The speed of applications and building a process takes place by using polyfills or modern syntax. Moreover, differential loading also helps in saving 7 to 20 percent of bundle size on average.

Differential loading in Angular 8.0 forms a part of Manfred Steyer's project, ngx-build-modern. All bundling is done with the ng build command and the -prod extension, without requiring special actions.

Opt-In Usage Sharing

It acts as an addition to the Angular CLI that aligns Angular 8 with community needs. Angular needs to keep a tab on how developers use the platform and what improvements are required. This is done with the information on the command used and builds speed. You can share telemetry on CLI usage with your development team.

Angular emphasizes consent on data sharing, unlike other platforms that collect data by default on an opt-out basis. It stops when you command them not to. Others don’t even allow them to ask them to share telemetry.

Improved Web Worker Bundling

With CPU-intensive tasks, the best way to speed up the application and improve parallelizability is web workers. Web workers write code off the main thread and offload tasks to a background thread.

The code running in the web worker cannot exist in the same JavaScript file in the application. These two must be different. Those working with tools such as Angular CLI bundles JavaScript automatically into a as few files as possible.

With the new improvements, Angular 8.0 makes it possible to fully parallelized web worker bundling. It acts as a relief for front-end developers who face limitations in single-thread.

You can run the following if you want to create a new CLI with a web worker.

Ng Generate Web Worker My-Worker

On receiving the web worker, adopt the process to implement the web worker in your application. It is then bundled and code-split with the following line:

const worker = new Worker(`./my-worker.worker`, { type: `module` });

Angular Router Backwards Compatibility

Angular 8 comes with a backward compatibility mode which makes it simpler to upgrade the larger applications. The teams move to Angular with lazy loading of the AngularJS-based app’s parts, using the $route APIs.

FORMS

MarkAllAsTouched

MarkAllAsTouched is a method in Angular 8 used in the AbstractControl class.

It adds to the list of previous methods, such as  markAsDirty,  markAsTouched, and  markAsPending. The method gets available in all reactive form entities, since AbstractControl is the parent class of FormArrayFormGroup, and FormControl.

The method touches marks control and descendants as touched as shown below:

form.markAllAsTouched();

FormArray.clear

In Angular 8, the FormArray class offers a clear method, which quickly removes all control it contains. You no longer have to loop over every control one-by-one, as shown below:

// `users` is initialized with 2 users
const users = fb.array([user1, user2]);
users.clear();
// users is now empty
**ROUTER **

Location

To migrate to Angular 8, you should be aware of a few things added to the location services:

  • Offer access to the hostname, port, and protocol with platformLocation.
  • Get history.state with the new getState() method.
  • Ease testing with a MockPlatformLocation.

Lazy-Loading With Import Syntax

Lazy loading is a useful concept in Angular 8. It brings down the size of occasionally used files. It uses the standard dynamic import syntax from TypeScript, instead of the custom-string for lazy-loaded modules. The syntax has similarities with ECMAScript standard and supported only by Ivy.

So, what earlier looked like:

{ path: '/student', loadChildren: './student/student.module#StudentModule' }  

Now, looks as:

{ path: '/student', loadChildren: () => import('./student/student.module').then(s => s.StudentModule) } 

Service Worker

A service worker in Angular is a script that runs in a web browser and manages cache for an application. It augments the traditional web deployment model and empowers the application to deliver a reliable user experience with performance on par with natively-installed code.

Registration Strategy

In previous versions, the Service worker was waiting for a stable application to register. This was used to avoid slowing the start of an application. The new option has an option that specifies when the registration will take place.

However, if starting a recurring asynchronous task in the previous versions would never be considered by Angular as stable, the service work would not have registered.

But, with Angular 8, this is possible with the option of registrationStrategy for handling the registration for a service worker with the following values:

  • The default value is registerWhenStable.
  • Register immediately with registerImmediately, with no need to wait for the app and registers, right away.
  • Delay in milliseconds in $TIMEOUT with registerDelay:$TIMEOUT.
  • A custom strategy defines a return value as Observable. The Service Worker registers with the first value of the Observable.

Here is code snippet for Service Worker registration after 4 seconds:

**Bypass a Service Worker **

You can use the ngsw-bypass header, for bypassing the service worker with a specified request, as shown in the below code:

this.http.get(‘api/users’, { headers: { ‘ngsw-bypass’: true } });

Multiple Apps on SubDomains

Earlier it was not possible to use multiple applications for using @angular/service-worker with different sub-paths for the same domain. It was because the cache of each service worker overwrote the cache of others. This error gets fixed in this version.

**T****ypeScript 3.4 **

It is now mandatory for Angular 8 to use TypeScript 3.4. The development team must upgrade the TypeScript. It helps when using readable and clean JavaScript code. TypeScript 3.4 introduces a new flag named incremental. It saves information from the project graph from the last compilation. While using Incremental, the information detects the least costly way to emit changes for your project and type-check.

**Workspace APIs and Builder APIs in CLI **

Angular 8 has new builder APIs to tap ng build, ng test, and ng run. It has similarities with schematics that taps into ng addng generateng update, and  ng new.

It uses third-party tools and libraries to assist you in processes such as building and deployment. Moreover, Angular leverages Cloud for APIs. AngularFire is the official library that connects Angular with Firebase. AngularFire adds the deploy command to simplify the process of deployment and build by Firebase with the following:

ng add @angular/fire
ng run my-app:deploy

Moreover, in earlier version, for changes in workspace configuration, angular.json was modified manually using Schematics. But the new API, in the current version, makes it simpler to modify and read a file.

**AngularJS Migration **

Angular 8 enables the users of $location services, as it now allows a Location Upgrade Module in the AngularJS applications. It helps to translate the unified location service and shifts the responsibility from AngularJS $location to the Angular Location. It eases our applications with hybrid operations and depends on the upgrade along with route in AngularJS and part.

**Bazel **

The latest Angular version makes it easier to build CLI applications. All this is due to Bazel, developed by Google. It is a build tool that works well with any language inputs. Some benefits of Bazel are:

  • Build frontend and backend with the same tool.
  • Gain on rebuild time with tests and incremental builds.
  • Gain cache and remote builds on build farms.
  • Allow tasks with clear input or output with Bazel and ensure that all the necessary tasks run.

About IVY

Ivy is the prime feature of Angular 8 and included as an opt-in preview for testing. Ivy is a new compiler to build next-gen rendering pipelines in the current version. It increases the efficiency of the latest version. It helps to improve runtime speed with simplified incremental compiling with its ability to generate bundles of significantly smaller size.

Moreover, it uses the concept of incremental DOM, where each component gets compiled with a set of instructions that constitutes the DOM tree. It updates it with a change in data.

Developers can use Ivy to determine the potential and performance of Angular applications. It never alters any of the existing applications. On completion, it will make the Angular applications smaller, simpler, and faster.

Two Primary Concepts of Ivy

Local : Recompile only the changed components and allow quicker compiling.

**Treeshakable: **The unused code gets removed so that the application concentrates on the code used. Ivy acts beneficially when the UI of the application is clear to the developer.

Advantages of IVY

The advantages of Ivy are:

  • Smaller Bundles.
  • Reduced Payload Size.
  • Faster Rebuild times.
  • Enhance Backwards Compatibility .
  • Pre-compiled Code shipment .
  • Dismissal of metadata.json.
  • Rise of meta programming.
  • Improve template type checking.
  • Broad Compatibility with existing Angular applications.

**Notable Changes **

The angular team makes your life easier with Schematics. Schematic updates your code by simply running:

ng update @angular/cor

Query Timing

The decorators, ViewChild and ContentChild, now have a new option called static. If the queried element is static (not wrapped in ngIf and ngFor. Thenm, it is available in ngOnInit:

So,

<h1 #staticDiv>static</h1>

Gives

@ViewChild('staticDiv') staticDiv: ElementRef<HTMLDivElement>;

ngOnInit() {
  console.log('init static', this.staticDiv); // div
}

ngAfterViewInit() {
  console.log('after view init static', this.staticDiv); // div
}

A static flag, when introduced, not only breaks existing applications, but you can use the following to keep the old behavior, even when switching to Ivy. It ensures the same behavior as the current one.

@ViewChild('static', { static: true }) static: ElementRef<HTMLDivElement>;

You can check with the query migration guide for further information.

Template Variable ReAssignment

View Engine allowed the following:

<button
  *ngFor="let option of options"
  (click)="option = 'newButtonText'">{{ option }}</button>

However, this is no longer possible in Ivy. It does not allow us to assign a value to a template variable like an option in the above example.

When you upgrade to Angular 8 to prepare for the switch to Ivy, a schematic analyzes the template and issues a warning for such a case.

The option left is to fix it manually.

<button
  *ngFor="let option of options; index as index"
  (click)="options[index] = 'newButtonText'">{{ option }}</button>

**Document **

The token DOCUMENT gets moved from the @angular/platform-browser to  @angular/common. It is manually possible to change it with a schematic provided for the purpose.

**Remove Deprecated HTTP Package **

Angular 8 removed @angular/http replaced with @angular/common/http as in Angular 4.3. A schematic removes the dependency in package.json.

**Deprecated Web Worker Package **

The @angular/common/http package enables you to run an application in the Web Worker. It is included in the deprecated packages list and will be removed in the future.

You can find the list of all deprecated API packages obtained here. 

How to Update Angular 7 to Angular 8

Some of the things to consider are:

  • TypeScript 3.4 may cause some syntax error.
  • Run the $ node-vcommand to check the version of Node running in your system. You need to run Node 12 and beyond for the upgrade.
  • Run $ ng update @angular/material to run the Angular Material in the application.
**Conclusion **

Other than Ivy, the additions to Angular 8 are not that critical or significant. You can gather insights on the Ivy preview from the official Ivy guide provided. However, it is recommended to upgrade to Angular 8 to ensure that your apps are all ready for Ivy.

Moreover, Ivy will become the default in the next version of Angular, so now it the best option for you to check whether your apps are going to need any changes. Thank you !

Microfrontends — Connecting JavaScript frameworks together (React, Angular, Vue etc)

Microfrontends — Connecting JavaScript frameworks together (React, Angular, Vue etc)

React, Angular, Vue, Ember, Backbone, Stencil, Preact…. in fact there’s probably another one being released right now. Microfrontends — bringing JavaScript frameworks together (React, Angular, Vue etc)

Like most things in life, a variety of choices informs a toxic culture of mine is better than yours and you’re wrong and I’m right.

Since technology advancements have got us in this mess, is there any chance it could get us out of it as well?

Enter Microfrontends…

Introduction to Microfrontends

Modern UI development regardless of your framework has became all about component composition: You adapt to a framework’s way of doing things by following their patterns and conventions to create components usually underpinned by some sort of data model usually in the form of a service or state object.

For example: Angular has a strong opinion on how everything should be architected in the frontend. React although it only deals with components has a huge ecosystem backing it driven by a community of React-centric developers.

**Microfrontends **have gathered huge momentum recently as away of allowing multiple teams to work on a single UI using multiple frameworks, but could it really change the landscape of UI development?

In this article, I am going to spend some time looking at the SDLC (software development lifecycle) and the advantages of adopting such an architecture.

Where’s the problem?

The current trend in UI development, is to build a feature-rich and powerful browser application (single page application) using a chosen framework.

Development results in building lots of little components which are then bundled together in some sort of build process using something like webpack or rollup.

Over time the UI layer often developed by separate or multiple teams, grows and gets more difficult to maintain creating a huge monolithic frontend.

Monolithic frontend SDLC

Monolithic frontends deployment architecture

Reversing the microservice anti-pattern:

Microfrontends looks at removing that monolithic build step, and results in completely decoupled services that can be independently built and deployed:

Microfrontend SDLC

Microfrontend deployment architecture

Now our UI architecture has all the qualities of traditional microservices:

  • Highly maintainable and testable
  • Loosely coupled
  • Independently deployable
  • Organised around business capabilities
How could this bring the big frameworks together?

Since we have decoupled our UI components into many microfrontends, we no longer have to dictate which framework each component uses.

The below illustration shows how we could potentially have different application teams using different technologies to create their independently built and released microfrontend:

SDLC using multiple frameworks

There are **several ways **to solve this using technologies but let me illustrate one example:

  1. **Develop: **Three teams using a different JavaScript framework for each microfrontend
  2. Build: Wrapping their microfrontend components as web components*** ***and building their project as a JavaScript file
  3. Release: A single JavaScript file is released inside a docker container served using Ngnix

Once we have released our microfrontends, we should compose them together in a single UI layer. The communication between the microfrontends should be handled by the composition layer which should have a well defined contract.

Deployment architecture using multiple frameworks

From a user perspective they access a single application, but the developer’s ability to solve a problem is no longer limited by what single framework the application uses.

Thanks for reading

If you liked this post, please do share/like it with all of your programming buddies!

Follow us on Facebook | Twitter

Further reading about JavaScript

The Complete JavaScript Course 2019: Build Real Projects!

Vue JS 2 - The Complete Guide (incl. Vue Router & Vuex)

JavaScript Bootcamp - Build Real World Applications

The Web Developer Bootcamp

New ES2019 Features Every JavaScript Developer Should Know

Best JavaScript Frameworks, Libraries and Tools to Use in 2019

Top 50 Interview Questions for JavaScript Developer

Vue.js Tutorial: Zero to Sixty

React vs Angular vs Vue.js by Example

Build a Basic CRUD App with Vue.js and Node

Angular 7 CRUD with Nodejs and MySQL Example

Angular 7 CRUD with Nodejs and MySQL Example

Angular7 CRUD with nodejs and mysql example - Hey there, Today we will proceed to create a demo for CRUD with Mysql, Express, Angular7(MEAN) and Nodejs from scratch using Angular CLI

Below are the requirements for creating the CRUD on MEAN

  • Node.js
  • Angular CLI
  • Angular 7
  • Mysql
  • IDE or Text Editor

We assume that you have already available the above tools/frameworks and you are familiar with all the above that what individually actually does.

So now we will proceed step by step to achieve the task.

1. Update Angular CLI and Create Angular 7 Application

At first, We have to update the Angular CLI to the latest version. Open the terminal then go to the project folder and then type the below command to update the Angular CLI

sudo npm install -g @angular/cli

Once the above task finishes, Next task is to create new angular application with below command. So go to your project folder and then type below command:

ng new angular7-crud

then go to the newly created folder of angular application with cd /angular7-crud  and type **ng serve. **Now, open the browser then go to http://localhost:4200 you should see this page.

2. Create a server with node.js express and Mysql for REST APIs

create a separate folder named server for server-side stuff, Then move inside folder and create server.js by typing touch server.js

Let’s have a look on the server.js file

let app = require('express')(),
server = require('http').Server(app),
bodyParser = require('body-parser')
express = require('express'),
cors = require('cors'),
http = require('http'),
path = require('path');
 
let articleRoute = require('./Routes/article'),
util = require('./Utilities/util');
 
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false }));
 
app.use(cors());
 
app.use(function(err, req, res, next) {
return res.send({ "statusCode": util.statusCode.ONE, "statusMessage": util.statusMessage.SOMETHING_WENT_WRONG });
});
 
app.use('/article', articleRoute);
 
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next();
});
 
/*first API to check if server is running*/
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, '../server/client/dist/index.html'));
})
 
 
server.listen(3000,function(){
console.log('app listening on port: 3000');
});

In the above file we can see, at the top, there are required packages for the app. Below that body parsing, middleware and routing is done.

The next task is to create routes and create a file article.js . So creating a folder name ‘Routes’ and adding article.js within it.

Add the below code for routing in article.js inside routing folder

let express = require('express'),
router = express.Router(),
util = require('../Utilities/util'),
articleService = require('../Services/article');
 
/**Api to create article */
router.post('/create-article', (req, res) => {
articleService.createArticle(req.body, (data) => {
res.send(data);
});
});
 
// /**Api to update article */
router.put('/update-article', (req, res) => {
articleService.updateArticle(req.body, (data) => {
res.send(data);
});
});
 
// /**Api to delete the article */
router.delete('/delete-article', (req, res) => {
articleService.deleteArticle(req.query, (data) => {
res.send(data);
});
});
 
/**Api to get the list of article */
router.get('/get-article', (req, res) => {
documentService.getArticle(req.query, (data) => {
res.send(data);
});
});
 
// /**API to get the article by id... */
router.get('/get-article-by-id', (req, res) => {
articleService.getArticleById(req.query, (data) => {
res.send(data);
});
});
 
module.exports = router;

Now create a folder named Utilities for all config, common methods and mysql connection config.

Now I am adding config values in a file named config.js

let environment = "dev";
 
let serverURLs = {
"dev": {
"NODE_SERVER": "http://localhost",
"NODE_SERVER_PORT": "3000",
"MYSQL_HOST": 'localhost',
"MYSQL_USER": 'root',
"MYSQL_PASSWORD": 'password',
'MYSQL_DATABASE': 'demo_angular7_crud',
}
}
 
let config = {
"DB_URL_MYSQL": {
"host": `${serverURLs[environment].MYSQL_HOST}`,
"user": `${serverURLs[environment].MYSQL_USER}`,
"password": `${serverURLs[environment].MYSQL_PASSWORD}`,
"database": `${serverURLs[environment].MYSQL_DATABASE}`
},
"NODE_SERVER_PORT": {
"port": `${serverURLs[environment].NODE_SERVER_PORT}`
},
"NODE_SERVER_URL": {
"url": `${serverURLs[environment].NODE_SERVER}`
}
};
 
module.exports = {
config: config
};

Now configure mysql connection. So I am writing the connection with database in a separate file. So creating a file named mysqkConfig.js under Utilities folder and adding the below line of code for mysql connection:

var config = require("../Utilities/config").config;
var mysql = require('mysql');
var connection = mysql.createConnection({
host: config.DB_URL_MYSQL.host,
user: config.DB_URL_MYSQL.user,
password: config.DB_URL_MYSQL.password,
database: config.DB_URL_MYSQL.database,
});
 
connection.connect(() => {
require('../Models/Article').initialize();
});
 
let getDB = () => {
return connection;
}
 
module.exports = {
getDB: getDB
}

Now I am creating separate file name util.js to save common methods and common status code/message:

// Define Error Codes
let statusCode = {
OK: 200,
FOUR_ZERO_FOUR: 404,
FOUR_ZERO_THREE: 403,
FOUR_ZERO_ONE: 401,
FIVE_ZERO_ZERO: 500
};
 
// Define Error Messages
let statusMessage = {
SERVER_BUSY : 'Our Servers are busy. Please try again later.',
DATA_UPDATED: 'Data updated successfully.',
DELETE_DATA : 'Delete data successfully',
 
};
 
module.exports = {
statusCode: statusCode,
statusMessage: statusMessage
}

Now the next part is model, So create a folder named Models and create a file **Article.js **and add the below code in it:

let mysqlConfig = require("../Utilities/mysqlConfig");
 
let initialize = () => {
mysqlConfig.getDB().query("create table IF NOT EXISTS article (id INT auto_increment primary key, category VARCHAR(30), title VARCHAR(24))");
 
}
 
module.exports = {
initialize: initialize
}

Now create DAO folder and add a file articleDAO.js for writting the mysql queries common functions:

let dbConfig = require("../Utilities/mysqlConfig");


 
let getArticle = (criteria, callback) => {
//criteria.aricle_id ? conditions += ` and aricle_id = '${criteria.aricle_id}'` : true;
dbConfig.getDB().query(`select * from article where 1`,criteria, callback);
}
 
let getArticleDetail = (criteria, callback) => {
    let conditions = "";
criteria.id ? conditions += ` and id = '${criteria.id}'` : true;
dbConfig.getDB().query(`select * from article where 1 ${conditions}`, callback);
}
 
let createArticle = (dataToSet, callback) => {
console.log("insert into article set ? ", dataToSet,'pankaj')
dbConfig.getDB().query("insert into article set ? ", dataToSet, callback);
}
 
let deleteArticle = (criteria, callback) => {
let conditions = "";
criteria.id ? conditions += ` and id = '${criteria.id}'` : true;
console.log(`delete from article where 1 ${conditions}`);
dbConfig.getDB().query(`delete from article where 1 ${conditions}`, callback);
 
}
 
let updateArticle = (criteria,dataToSet,callback) => {
    let conditions = "";
let setData = "";
criteria.id ? conditions += ` and id = '${criteria.id}'` : true;
dataToSet.category ? setData += `category = '${dataToSet.category}'` : true;
dataToSet.title ? setData += `, title = '${dataToSet.title}'` : true;
console.log(`UPDATE article SET ${setData} where 1 ${conditions}`);
dbConfig.getDB().query(`UPDATE article SET ${setData} where 1 ${conditions}`, callback);
}
module.exports = {
getArticle : getArticle,
createArticle : createArticle,
deleteArticle : deleteArticle,
updateArticle : updateArticle,
getArticleDetail : getArticleDetail
}

Now one create Services folder and add a file article.js for all the logic of API

let async = require('async'),
parseString = require('xml2js').parseString;
 
let util = require('../Utilities/util'),
articleDAO = require('../DAO/articleDAO');
//config = require("../Utilities/config").config;
 
 
/**API to create the atricle */
let createArticle = (data, callback) => {
async.auto({
article: (cb) => {
var dataToSet = {
"category":data.category?data.category:'',
"title":data.title,
}
console.log(dataToSet);
articleDAO.createArticle(dataToSet, (err, dbData) => {
if (err) {
cb(null, { "statusCode": util.statusCode.FOUR_ZERO_ONE, "statusMessage": util.statusMessage.SERVER_BUSY });
return;
}
 
cb(null, { "statusCode": util.statusCode.OK, "statusMessage": util.statusMessage.DATA_UPDATED,"result":dataToSet });
});
}
//]
}, (err, response) => {
callback(response.article);
});
}
 
/**API to update the article */
let updateArticle = (data,callback) => {
async.auto({
articleUpdate :(cb) =>{
if (!data.id) {
cb(null, { "statusCode": util.statusCode.FOUR_ZERO_ONE, "statusMessage": util.statusMessage.PARAMS_MISSING })
return;
}
console.log('phase 1');
var criteria = {
id : data.id,
}
var dataToSet={
"category": data.category,
"title":data.title,
}
console.log(criteria,'test',dataToSet);
                    articleDAO.updateArticle(criteria, dataToSet, (err, dbData)=>{
                        if(err){
cb(null,{"statusCode":util.statusCode.FOUR_ZERO_ONE,"statusMessage":util.statusMessage.SERVER_BUSY});
                        return; 
                        }
                        else{
cb(null, { "statusCode": util.statusCode.OK, "statusMessage": util.statusMessage.DATA_UPDATED,"result":dataToSet });                        
                        }
                    });
}
}, (err,response) => {
callback(response.articleUpdate);
});
}
 
/**API to delete the subject */
let deleteArticle = (data,callback) => {
console.log(data,'data to set')
async.auto({
removeArticle :(cb) =>{
if (!data.id) {
cb(null, { "statusCode": util.statusCode.FOUR_ZERO_ONE, "statusMessage": util.statusMessage.PARAMS_MISSING })
return;
}
var criteria = {
id : data.id,
}
articleDAO.deleteArticle(criteria,(err,dbData) => {
if (err) {
console.log(err);
cb(null, { "statusCode": util.statusCode.FOUR_ZERO_ONE, "statusMessage": util.statusMessage.SERVER_BUSY });
return;
}
cb(null, { "statusCode": util.statusCode.OK, "statusMessage": util.statusMessage.DELETE_DATA });
});
}
}, (err,response) => {
callback(response.removeArticle);
});
}
 
/***API to get the article list */
let getArticle = (data, callback) => {
async.auto({
article: (cb) => {
articleDAO.getArticle({},(err, data) => {
if (err) {
cb(null, {"errorCode": util.statusCode.INTERNAL_SERVER_ERROR,"statusMessage": util.statusMessage.SERVER_BUSY});
return;
}
cb(null, data);
return;
});
}
}, (err, response) => {
callback(response.article);
})
}
 
/***API to get the article detail by id */
let getArticleById = (data, callback) => {
async.auto({
article: (cb) => {
let criteria = {
"id":data.id
}
articleDAO.getArticleDetail(criteria,(err, data) => {
if (err) {
console.log(err,'error----');
cb(null, {"errorCode": util.statusCode.INTERNAL_SERVER_ERROR,"statusMessage": util.statusMessage.SERVER_BUSY});
return;
}
cb(null, data[0]);
return;
});
}
}, (err, response) => {
callback(response.article);
})
}
 
module.exports = {
createArticle : createArticle,
updateArticle : updateArticle,
deleteArticle : deleteArticle,
getArticle : getArticle,
getArticleById : getArticleById
};

3. Create angular component for performing CRUD task of article

ng g component article

Above command will generate all required files for build article component and also automatically added this component to app.module.ts.

create src/app/article/article.component.css (0 bytes)
create src/app/article/article.component.html (23 bytes)
create src/app/article/article.component.spec.ts (614 bytes)
create src/app/article/article.component.ts (321 bytes)
update src/app/app.module.ts (390 bytes)

Now we need to add HttpClientModule to app.module.ts. Open and edit src/app/app.module.ts then add this import. And add it to @NgModule imports after BrowserModule. Now our app.module.ts will have following code:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ReactiveFormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
 
import { AppComponent } from './app.component';
import { ArticleComponent } from './article.component';
import { ArticleService } from './article.service';
 
@NgModule({
imports: [
BrowserModule,
HttpModule,
ReactiveFormsModule
],
declarations: [
AppComponent,
ArticleComponent
],
providers: [
ArticleService
],
bootstrap: [
AppComponent
]
})
export class AppModule { }

Now create a service file where we will make all the request to the server for CRUD operation. Command for creating service is ng g service artcle , for now I have just created a file named it article.service.ts. Let's have a look in the code inside this file.

import { Injectable } from '@angular/core';
import { Http, Response, Headers, URLSearchParams, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
 
import { Article } from './article';
 
@Injectable()
export class ArticleService {
//URL for CRUD operations
    articleUrl = "http://localhost:3000/article";
    //Create constructor to get Http instance
    constructor(private http:Http) {
    }
    
    //Fetch all articles
getAllArticles(): Observable<Article[]> {
return this.http.get(this.articleUrl+"/get-article")
              .map(this.extractData)
         .catch(this.handleError);
 
}
    //Create article
createArticle(article: Article):Observable<number> {
     let cpHeaders = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: cpHeaders });
return this.http.post(this.articleUrl+"/create-article", article, options)
.map(success => success.status)
.catch(this.handleError);
}
    //Fetch article by id
getArticleById(articleId: string): Observable<Article> {
        let cpHeaders = new Headers({ 'Content-Type': 'application/json' });
        let options = new RequestOptions({ headers: cpHeaders });
        console.log(this.articleUrl +"/get-article-by-id?id="+ articleId);
        return this.http.get(this.articleUrl +"/get-article-by-id?id="+ articleId)
             .map(this.extractData)
             .catch(this.handleError);
}   
    //Update article
updateArticle(article: Article):Observable<number> {
     let cpHeaders = new Headers({ 'Content-Type': 'application/json' });
        let options = new RequestOptions({ headers: cpHeaders });
return this.http.put(this.articleUrl +"/update-article", article, options)
.map(success => success.status)
.catch(this.handleError);
}
//Delete article    
deleteArticleById(articleId: string): Observable<number> {
        let cpHeaders = new Headers({ 'Content-Type': 'application/json' });
        let options = new RequestOptions({ headers: cpHeaders });
        return this.http.delete(this.articleUrl +"/delete-article?id="+ articleId)
             .map(success => success.status)
             .catch(this.handleError);
}   
    private extractData(res: Response) {
        let body = res.json();
return body;
}
private handleError (error: Response | any) {
        console.error(error.message || error);
        return Observable.throw(error.status);
}
}

In the above file we have made all the http request for the CRUD operation. Observables of rxjs library has been used to handle the data fetching from http request.

Now let's move to the next file, article.component.ts. Here we have all the login part of the app. Let's have a look code inside this file:

import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
 
import { ArticleService } from './article.service';
import { Article } from './article';
 
@Component({
selector: 'app-article',
templateUrl: './article.component.html',
styleUrls: ['./article.component.css']
})
export class ArticleComponent implements OnInit {
//Component properties
allArticles: Article[];
statusCode: number;
requestProcessing = false;
articleIdToUpdate = null;
processValidation = false;
//Create form
articleForm = new FormGroup({
title: new FormControl('', Validators.required),
category: new FormControl('', Validators.required)   
});
//Create constructor to get service instance
constructor(private articleService: ArticleService) {
}
//Create ngOnInit() and and load articles
ngOnInit(): void {
     this.getAllArticles();
}
//Fetch all articles
 
getAllArticles() {
        this.articleService.getAllArticles()
         .subscribe(
data => this.allArticles = data,
                errorCode => this.statusCode = errorCode);
                
}
//Handle create and update article
onArticleFormSubmit() {
     this.processValidation = true;
     if (this.articleForm.invalid) {
     return; //Validation failed, exit from method.
     }
     //Form is valid, now perform create or update
this.preProcessConfigurations();
     let article = this.articleForm.value;
     if (this.articleIdToUpdate === null) {
     //Generate article id then create article
this.articleService.getAllArticles()
     .subscribe(articles => {
            
         //Generate article id    
         let maxIndex = articles.length - 1;
         let articleWithMaxIndex = articles[maxIndex];
         let articleId = articleWithMaxIndex.id + 1;
         article.id = articleId;
         console.log(article,'this is form data---');
         //Create article
    this.articleService.createArticle(article)
             .subscribe(successCode => {
                    this.statusCode = successCode;
                    this.getAllArticles();  
                    this.backToCreateArticle();
                 },
                 errorCode => this.statusCode = errorCode
             );
         });        
     } else {
  //Handle update article
article.id = this.articleIdToUpdate;        
     this.articleService.updateArticle(article)
     .subscribe(successCode => {
         this.statusCode = successCode;
                 this.getAllArticles();  
                    this.backToCreateArticle();
             },
         errorCode => this.statusCode = errorCode);  
     }
}
//Load article by id to edit
loadArticleToEdit(articleId: string) {
this.preProcessConfigurations();
this.articleService.getArticleById(articleId)
     .subscribe(article => {
            console.log(article,'poiuytre');
         this.articleIdToUpdate = article.id;
                    this.articleForm.setValue({ title: article.title, category: article.category });
                    this.processValidation = true;
                    this.requestProcessing = false;
         },
         errorCode => this.statusCode = errorCode);
}
//Delete article
deleteArticle(articleId: string) {
this.preProcessConfigurations();
this.articleService.deleteArticleById(articleId)
     .subscribe(successCode => {
         //this.statusCode = successCode;
                    //Expecting success code 204 from server
                    this.statusCode = 204;
                 this.getAllArticles();  
                 this.backToCreateArticle();
             },
         errorCode => this.statusCode = errorCode);
}
//Perform preliminary processing configurations
preProcessConfigurations() {
this.statusCode = null;
     this.requestProcessing = true;
}
//Go back from update to create
backToCreateArticle() {
this.articleIdToUpdate = null;
this.articleForm.reset(); 
     this.processValidation = false;
}
}

Now we have to show the task over browser, So lets have a look inside article.component.html file.

<h1 class="text-center">Angular 7 CRUD Demo App</h1>
<h3 class="text-center" *ngIf="articleIdToUpdate; else create">
Update Article for Id: {{articleIdToUpdate}}
</h3>
<ng-template #create>
<h3 class="text-center"> Create New Article </h3>
</ng-template>
<div>
<form [formGroup]="articleForm" (ngSubmit)="onArticleFormSubmit()">
<table class="table-striped" style="margin:0 auto;">
<tr><td>Enter Title</td><td><input formControlName="title">
   <label *ngIf="articleForm.get('title').invalid && processValidation" [ngClass] = "'error'"> Title is required. </label>
 </td></tr>
<tr><td>Enter Category</td><td><input formControlName="category">
   <label *ngIf="articleForm.get('category').invalid && processValidation" [ngClass] = "'error'"> Category is required. </label>
  </td></tr>  
<tr><td colspan="2">
   <button class="btn btn-default" *ngIf="!articleIdToUpdate">CREATE</button>
    <button class="btn btn-default" *ngIf="articleIdToUpdate">UPDATE</button>
   <button (click)="backToCreateArticle()" *ngIf="articleIdToUpdate">Go Back</button>
  </td></tr>
</table>
</form>
<br/>
<div class="text-center" *ngIf="statusCode; else processing">
<div *ngIf="statusCode === 201" [ngClass] = "'success'">
   Article added successfully.
</div>
<div *ngIf="statusCode === 409" [ngClass] = "'success'">
Article already exists.
</div>   
<div *ngIf="statusCode === 200" [ngClass] = "'success'">
Article updated successfully.
</div>   
<div *ngIf="statusCode === 204" [ngClass] = "'success'">
Article deleted successfully.
</div>   
<div *ngIf="statusCode === 500" [ngClass] = "'error'">
Internal Server Error.
</div> 
</div>
<ng-template #processing>
  <img *ngIf="requestProcessing" src="assets/images/loading.gif">
</ng-template>
</div>
<h3 class="text-center">Article List</h3>
<table class="table-striped" style="margin:0 auto;" *ngIf="allArticles">
<tr><th> Id</th> <th>Title</th><th>Category</th><th></th><th></th></tr>
<tr *ngFor="let article of allArticles" >
<td>{{article.id}}</td> <td>{{article.title}}</td> <td>{{article.category}}</td>
  <td><button class="btn btn-default" type="button" (click)="loadArticleToEdit(article.id)">Edit</button> </td>
  <td><button class="btn btn-default" type="button" (click)="deleteArticle(article.id)">Delete</button></td>
</tr>
</table>

Now since I have created server and client two separate folder for nodejs and angular task. So will run both the apps with npm start over two tabs of terminal.

On the browser, over link http://localhost:4200. App will look like below

That’s all for now. Thank you for reading and I hope this post will be very helpful for creating CRUD operations with angular7,node.js & mysql.

================================================

Thanks for reading :heart: If you liked this post, share it with all of your programming buddies! Follow me on Facebook | Twitter

Best JavaScript Frameworks, Libraries and Tools to Use in 2019

Best JavaScript Frameworks, Libraries and Tools to Use in 2019

JavaScript (JS) is a lightweight interpreted or just-in-time compiled programming language with first-class functions. Here we have listed best JavaScript frameworks, libraries and tools to use in 2019

JavaScript (JS) is a lightweight interpreted or just-in-time compiled programming language with first-class functions. Here we have listed best JavaScript frameworks, libraries and tools to use in 2019

It seems there are more JavaScript frameworks, libraries, and **tools **than there are developers. At the end of 2018, a quick search on GitHub reveals 2.3 million JavaScript projects. npm has become the world’s largest module system with 700,000 usable packages on npmjs.com and billions of downloads every month.

This article endeavors to explain the basics and rudimentary differences between the most popular client-side JavaScript frameworks, libraries, and tools. Whether they are “best” for you is another question. Choose something and stick with it for a while. Just be aware your favorite option will be superseded by something “better” no matter what you select!

Table of Contents
  • Table of Contents
  • Tricky Terminology
  • Libraries
  • Frameworks
  • Tools
  • Don't Label Me!
  • JavaScript Frameworks and Libraries
  • jQuery
  • React
  • AngularJS 1.x
  • Angular 2+ (now 7.x)
  • Vue.js
  • Sencha Ext JS
  • Lodash and Underscore
  • Backbone.js
  • Ember.js
  • Knockout.js
  • Notable Mentions
  • Tools: General-Purpose Task Runners
  • Webpack
  • Gulp.js
  • npm
  • Grunt
  • Tools: Module Bundlers
  • Browserify
  • RequireJS
  • Tools: Linting
  • ESLint
  • JSHint
  • JSLint
  • Tools: Test Suites
  • Jest
  • Mocha
  • Jasmine
  • Tools: Miscellaneous
  • Summary and Recommendations
  • Comments

Please accept the following terms and conditions before reading this article!…

  • The JavaScript landscape changes on a daily basis. This article will be out of date the moment it’s published!
  • By "best" I mean "the most popular/used/hyped general-purpose projects". All have free/open source options but the list may not include your favorites.
  • Discontinued projects such as YUI are not included even though they may still have high use across the web.
  • Only client-side projects are referenced. Some can work server-side but the list does not include pure server-based frameworks such as Express.js or Hapi.
  • Information about each project is intentionally brief to provide an overview for further research.
  • Each project provides a usage popularity indicator but statistics are notoriously difficult to collate and can be misleading.
  • I’m biased. You’re biased. Everyone else is biased! I haven’t tried every tool here and will declare my favorites but you should make your own assessment based on your requirements.
  • Neither I or SitePoint are liable for any disastrous decisions you make!
Tricky Terminology

The terms "framework", "library" and "tool" can mean different things to different people at different times depending on the context. The general definitions used here:

JavaScript Libraries

A library is an organized collection of useful functionality. A typical library could include functions to handle strings, dates, HTML DOM elements, events, cookies, animations, network requests, and more. Each function returns values to the calling application which can be implemented however you choose. Think of it like a selection of car components: you’re free to use any to help construct a working vehicle but you must build the engine yourself.

Libraries normally provide a higher level of abstraction which smooths over implementation details and inconsistencies. For example, Ajax can be implemented using the XMLHttpRequest API but this requires several lines of code and there are subtle differences across browsers. A library may provide a simpler ajax() function so you’re free to concentrate on higher-level business logic.

A library could cut development time by 20% because you don’t have to worry about the finer details. The downsides:

  • a bug within a library can be difficult to locate and fix
  • there’s no guarantee the development team will release a patch quickly
  • a patch could change the API and incur significant changes to your code.
JavaScript Frameworks

A framework is an application skeleton. It requires you to approach software design in a specific way and insert your own logic at certain points. Functionality such as events, storage, and data binding are normally provided for you. Using the car analogy, a framework provides a working chassis, body, and engine. You can add, remove or tinker with some components presuming the vehicle remains operational.

A framework normally provides a higher level of abstraction than a library and can help you rapidly build the first 80% of your project. The downsides:

  • the last 20% can be tough going if your application moves beyond the confines of the framework
  • framework updates or migrations can be difficult – if not impossible
  • core framework code and concepts rarely age well. Developers will always discover a better way to do the same thing.
JavaScript Tools

A tool aids development but is not an integral part of your project. Tools include build systems, compilers, transpilers, code minifiers, image compressors, deployment mechanisms and more.

Tools should provide an easier development process. For example, many coders prefer Sass to CSS because it provides code separation, nesting, render-time variables, loops, and functions. Browsers do not understand Sass/SCSS syntax so the code must be compiled to CSS using an appropriate tool before testing and deployment.

Don’t Label Me!

The distinction between libraries, frameworks, and tools is rarely clear. A framework could include a library. A library may implement framework-like methods. Tools could be essential for either. I’ve attempted to label each project but the scope can vary.

If this sounds too complicated, you could consider coding vanilla JavaScript. That’s fine, but you will inevitably write your own library and/or framework code which must be maintained. JavaScript itself is an abstraction on a tower of browser and OS abstractions!

JavaScript Frameworks and Libraries

Projects in approximate order of usage/popularity/hype…

jQuery

jQuery remains the most-used JavaScript library ever created and is distributed with WordPress, ASP.NET and several other frameworks. It revolutionized client-side development by introducing CSS selector to DOM node retrieval plus chaining to apply event handlers, animations, and Ajax calls.

jQuery has fallen from developer favor in recent years, but usage remains high. It remains a viable option for projects which require a sprinkling of JavaScript functionality.

Pros:

  • small distribution size
  • shallow learning curve, considerable online help
  • concise syntax
  • easy to extend

Cons:

  • adds a speed overhead to native APIs
  • less essential now that browser compatibility has improved
  • usage has flat-lined
  • some industry backlash against unnecessary use.
React

Perhaps the most-talked about library of the last few years, React claims to be a JavaScript library for building user interfaces. It focuses on the "View" part of Model-View-Controller (MVC) development and makes it easy to create UI components which retain state. It was one of the first libraries to implement a virtual DOM; the in-memory structure computes the differences and updates the page efficiently.

React usage appears low in statistics perhaps because it’s used in applications rather than websites. Almost 70% of developers claim to have some experience using the library.

Pros:

  • small, efficient, fast and flexible
  • simple component model
  • good documentation and online resources
  • server-side rendering is possible
  • still popular and growing fast
  • plenty of jobs advertise for React developers

Cons:

  • new concepts and syntaxes to learn
  • build tools are essential
  • can require other libraries or frameworks to provide the model and controller aspects
  • can be incompatible with code and other libraries which modify the DOM
AngularJS 1.x

Angular is the first framework – or MVC application framework – to appear on this list. The most popular edition remains version 1.x which extended HTML with two-way data-binding while decoupling DOM manipulation from application logic.

Angular 1.x is still in development despite the release of version 2 (which is now version 4!) Confused? See below…

Pros:

  • a popular framework adopted by several large companies
  • a single solution to produce modern web applications
  • part of the "standard" MEAN stack (MongoDB, Express.JS, AngularJS, NodeJS) so many articles and tutorials are available

Cons:

  • steeper learning curve than some alternatives
  • large code base
  • impossible to upgrade to Angular 2.x
  • despite being a Google project, Google do not appear to use it?
Angular 2+ (now 7.x)

Angular 2.0 was released in September 2016. It was a complete rewrite which introduced a modular component-based model created with TypeScript (which is compiled to JavaScript). To add to the confusion, version 4.0 was released in March 2017 (v3 was skipped to avoid semantic version issues).

Angular 2+ is radically different to v1. Neither is compatible with the other – perhaps Google should have given the project a different name?!

Pros:

  • a single solution to produce modern web applications
  • still part of the MEAN stack although fewer Angular 2+ tutorials are available
  • TypeScript provides some advantages to those familiar with statically-typed languages such as C# and Java.

Cons:

  • steeper learning curve than some alternatives
  • large code base
  • impossible to upgrade from Angular 1.x
  • Angular 2.x has experienced relatively low uptake compared to 1.x
  • despite being a Google project, Google do not appear to use it?
Vue.js

Vue.js is a lightweight progressive framework for building user interfaces. The core offers a React-like virtual DOM-powered view layer which can be integrated with other libraries but it is also capable of powering single-page applications. The framework was created by Evan You who previously worked on AngularJS but wanted to extract the parts he liked.

Vue.js uses an HTML template syntax to bind the DOM to instance data. Models are plain JavaScript objects which update the view when data is changed. Additional tools provide facilities for scaffolding, routing, state management, animations and more.

Pros:

  • rapid adoption and increasing popularity
  • simple to get started with high level of developer satisfaction
  • lightweight, small dependency and good performance

Cons:

  • can be overshadowed by React
  • some reliance on a single developer for updates
  • fewer resources than alternatives
Sencha Ext JS

Ext JS evolved from YUI-Ext and has one of the longest histories on this list. Although best known for its wide range of configurable, accessible, cross-browser UI components and data visualisation tools, Ext JS also provides a framework for building full applications. Alternatively, you can use the component library with React or Angular.

Ext JS is the only framework here to offer commercial training and support. There are also options to have the Sencha team help review your code, automate testing, and migrate to other platforms.

Pros:

  • a wide range of usable components
  • contains everything required to create both web and mobile applications
  • script customization, design tools, and quick prototypes
  • provides tools for visually building and styling web apps
  • commercial support and excellent documentation
  • 30-day free trial and community edition for smaller applications (under a wide range of usable componentscontains everything required to create both web and mobile applicationsscript customization, design tools, and quick prototypesprovides tools for visually building and styling web appscommercial support and excellent documentation30-day free trial and community edition for smaller applications (under $10,000 revenue per year)0,000 revenue per year)

Cons:

  • integration with frameworks other than React and Angular may be impractical as of now — see roadmap plans for Ext JS 7
  • deep custom UI changes may be difficult
Lodash and Underscore

Lodash and Underscore are combined in this section because they provide hundreds of functional JavaScript utilities to supplement native string, number, array and other primitive object methods. There is some overlap so you are unlikely to require both libraries in a single project.

Client-side usage is low but either library can be adopted for server-side Node.js applications.

Pros:

  • small and simple
  • easy to learn with good documentation
  • compatible with most libraries and frameworks
  • does not extend built-in objects
  • can be used on the client or server

Cons:

  • some methods are available in ES2015 and later editions of JavaScript.
Backbone.js

Backbone.js was one of the earliest client-side options to provide an MVC structure commonly found in server-side frameworks. Its only dependency is Underscore.js which was created by the same developer.

Backbone.js claims to be a library because it can be integrated with other projects. I suspect most developers consider it to be a framework, albeit less opinionated than some others.

Pros:

  • small, lightweight and less complicated
  • does not add logic to HTML
  • great documentation
  • adopted for many applications including Trello, WordPress.com, LinkedIn and Groupon

Cons:

  • a lower level of abstraction than alternatives such as AngularJS (although that could be considered a benefit)
  • requires additional components to implement features such as data binding
  • more recent frameworks have moved away from MVC architectures
Ember.js

Ember.js is one of the larger opinionated frameworks which is based on a Model-View-ViewModel (MVVM) pattern. It implements templating, data-binding, and libraries in a single package. The convention-over-configuration concepts will be immediately familiar to those with Ruby on Rails experience.

Pros:

  • provides a single solution for client-side applications
  • developers can be instantly productive – it uses jQuery
  • good backward compatibility and upgrade options
  • has adopted modern web development standards

Cons:

  • large distributable
  • considered monolithic compared to other frameworks which are moving toward smaller component structures
  • steep learning curve – it’s the Ember way or no way
Knockout.js

One of the older MVVM frameworks, Knockout.js uses observers to ensure the UI stays synchronized with underlying data. It features templating and dependency tracking.

Pros:

  • small and lightweight with no dependencies
  • excellent browser support going back to IE6
  • good documentation

Cons:

  • larger projects can become complex
  • development has slowed
  • usage appears to be on the wane
Notable Mentions

Hungry for more? The following projects are less popular but worth

considering:

  • Polymer – a library which enables cross-browser support for HTML5 web components
  • Meteor – a full-stack platform for web applications.
  • Aurelia – a lightweight, cross-platform framework
  • Svelte – a fairly new project which transforms framework source code into vanilla-like JavaScript
  • Conditioner.js – a new library which automatically loads and unloads modules based on state.
JavaScript Tools: General-Purpose Task Runners

Build tools automate a variety of web development tasks such as pre-processing, compilation, module bundling, image optimization, code minification, linting, and running tests. Tasks are usually managed together in a single executable package. The most popular options:

Webpack

Webpack supports all popular module options and has become synonymous with React development. Although claiming to be a module bundler, Webpack can be used as a general-purpose task runner. JavaScript object-based configuration can be a little awkward.Generators are available but some Webpack users have been migrating to Parcel for easier configuration and improved compilation times.

Gulp.js

While it was not the first task runner, Gulp quickly became one of the most popular and is my personal favorite. Gulp uses easy-to-read JavaScript code which loads source files into a stream and pipes the data through various plugins before they are output to a build folder. It’s simple, fast and fun, but developers have been migrating to Webpack.

npm

npm is the Node.js package manager but its scripts facility can be used for general-purpose task running. It’s an attractive option for simpler projects with few dependencies. However, more complex tasks can rapidly become impractical.

Grunt

Grunt was one of the first JavaScript task runners to achieve mass adoption but the speed and complicated JSON configuration led to the rise of Gulp. The worst issues have been resolved and Grunt remains a popular option.

JavaScript Tools: Module Bundlers

Managing more than a few JavaScript files can become a chore. Unless you can adopt the relatively new ES6 module import syntax natively, JavaScript dependencies in the browser must be loaded or concatenated in an appropriate order. A module bundler can be used if you need to support older browsers (anything released prior to 2018) but the need to use these tools will diminish over time.

Browserify

Browserify supports CommonJS modules as used by Node.js to compile all modules into a single browser-compatible file.

RequireJS

RequireJS started life an in-browser module loader although it can also be used in Node.js. It supports AMD syntax.

JavaScript Tools: Linting

Linting analyses your code for potential errors or deviation from syntactical standards. You’ll never miss a closing bracket or undeclared variable again!

ESLint

ESLint is the most popular linting tool supported by the majority of IDEs, editors, bundlers, and task runners. Every rule is a plugin so it can be configured to your liking.

JSHint

A flexible JavaScript linter which is less configurable than ESLint but strikes a good balance between genuine errors and pedantic syntactical demands.

JSLint

One of the first linters and it implements a strict set of default rules. Development has slowed and it can be a little uncompromising for some developers.

JavaScript Tools: Test Suites

Test-Driven-Development requires you to write code to test your code before you start writing it. You’re welcome to write code to test your test code too!

There are many options including Ava, Tape and Jasmine but the three most popular options are currently…

Jest

A testing framework from Facebook which has risen in popularity because of its close connections with React and Webpack.

Mocha

Mocha can run tests in Node.js and a browser. It supports asynchronous testing and is often paired with Chai to enable test code to be expressed in a readable style. It was the most popular option for several years.

Jasmine

Jasmine is a behavior-driven test suite which can automate the testing your UI and interactions in a browser.

JavaScript Tools: Miscellaneous

Despite my best efforts, I accept not everyone loves JavaScript! Compilers such as TypeScript, LiveScript and CoffeeScript can make your development life a little more pleasurable. Alternatively, consider Babel to transform modern, concise ES2015 source into cross-browser-compatible ES5 code.

There are dozens of JavaScript-powered HTML template engines including Mustache, Handlebars, Pug (Jade) and EJS. I prefer lightweight options which retain JavaScript syntax such as EJS and doT.

Finally, why write your own documentation when you can automate it? ES2015-compatible documentation generators include ESDoc, JSDoc, YUIdoc, documentation.js and Transcription.

Summary and Recommendations

If you follow the wisdom of crowds, momentum is currently behind React and other libraries are moving in a similar technical direction. It’s a safe career choice but you should also consider Vue.js or the React-compatible-but-smaller Preact.

Monolithic frameworks have fallen from favor but, should you require a strict structure for larger projects, AngularJS remains a popular option. The majority of developers have stuck with version 1.0 but that’s possibly out of necessity than choice. Longer term, version 2+ could be a safer bet but you will need to learn TypeScript.

Sencha’s Ext JS is a great option for companies (small businesses to enterprises) looking for an option that includes both a framework and pre-built, integrated components and tools, including access to commercial support. Ext JS also easily integrates its robust component library with React and Angular, for developers looking to implement pre-built components as opposed to building them on their own.

Do not discount jQuery. It’s not trendy and is rarely mentioned in the technical press, but it’s actively developed and more than capable for websites and applications. jQuery has a shallow learning curve and is understood by many developers worldwide.

If you’re feeling adventurous, new transpiler options such as Svelte and Rawact convert framework code to vanilla JavaScript. The framework dependency is removed, code is considerably smaller and runs faster.

Tools choice is less critical and can vary from project to project. Most WebPack, Gulp or npm scripts. You can’t go far wrong with ESLint and Jest for testing but there are plenty of alternatives to try.

That said, every project, team and skill set is different. You have limited time to make an assessment so it’s tempting to use what you know. This article will receive comments recommending FrameworkX but everything looks like a nail when you have a hammer.

Finally, never forget that libraries, frameworks, and tools are optional! JavaScript development has been revolutionized during the past decade; we’ve gone from a few rudimentary helper libraries to an overwhelming choice. It’s easy to fall into a trap of ever-increasing complexity or switching to the latest hot framework every few months. Always consider vanilla JavaScript – especially for smaller and personal personal. The knowledge you gain cannot date and will become invaluable when evaluating frameworks for other projects.

Have I missed, dismissed, or failed to praise the benefits your favorite JavaScript libraries, frameworks and tools? Of course I have! Comments welcome…