Vue CLI 3 Full-Stack App Structure

Vue CLI 3 Full-Stack App Structure

But if the Vue app is the client layer of a full-stack JavaScript app, for example, in a “MEVN” configuration (Mongo, Express, Vue, Node), it’s not entirely clear how Vue CLI 3 should be integrated into such a structure.

There are several approaches you could reasonably take:

  1. Put your server in a completely separate repo
  2. Create a repo for your server and put your Vue CLI 3 scaffold in a sub-folder
  3. Create a “universal” structure by modifying your Vue CLI 3 scaffold to share with your server
  4. Conclude that it is not appropriate to use Vue CLI 3 for a full-stack structure and roll your own config.

The difficulty of choosing one of these options is that each has its own pros and cons when it comes to balancing best practices, maintainability, ease of use, ease of testing and deployment etc.

Making this choice was of particular interest to me as I thought about the best approach to take for my Enterprise Vue course, which is centered around the creation of a MEVN app. I was hoping it would be possible to build this app and still take advantage of Vue CLI 3.


Deferring to authority and experience

As far as I know, there is no “official” example of Vue CLI 3 in a full-stack configuration, and I imagine there is unlikely to ever be.

But we can look at how other JavaScipt frameworks have tackled this issue.

A popular and well-respected full-stack app boilerplate is the one outlined at mean.io for a full-stack Angular app.

This boilerplate, and in fact almost all of the full-stack JavaScript boilerplates I could find, use the universal approach I mentioned, where both the client and server share the same directory, giving you a structure like this:

<pre class="ql-syntax" spellcheck="false">- client - components ... main.js - server - routes ... index.js ... package.json ...

</pre>

Interestingly, the mean.io boilerplate also includes Angular CLI.


Universal folder structure pros and cons

By looking at examples out on in the wild, it seems this approach is the most popular way to structure a full-stack JS app.

Some of the advantages I can see are:

  • It’s efficient, as it allows you to share package.json, node_modules, environment variables and opens the possibility of common code between client and server.
  • It makes installation and deployment easy, as one command in package.json can be used to install/deploy the whole app.
  • It’s easy to read and understand.

The disadvantage is that if you want to use this app structure with Vue CLI 3, you’ll need to modify the scaffold, which is not without its shortcomings.


Accommodating a server in a Vue CLI 3 scaffold

Vue CLI 3 hasn’t been designed to share its space with a server. By going down this path a few of the problems you’ll face include:

  • It doesn’t like you to change the file structure. For example, the src folder can’t easily be renamed.
  • It hijacks the .env file and important environment variables like PORT which are normally reserved for the server.
  • Some out-of-the-box config like ESLint is not appropriate for server files, so you’ll have to manually update them.

None of these problems are insurmountable, though, and if you can get through them you’ll have a clean, maintainable folder structure, with the best practices and zero-config advantages of Vue CLI 3.


Learn More

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

Nuxt.js - Vue.js on Steroids

Build Web Apps with Vue JS 2 & Firebase

Build a CMS with Laravel and Vue

Vuejs 2 Authentication Tutorial

Build a Progressive Web App In VueJs

Vue.js Tutorial for beginners

Originally published by Anthony Gore at https://vuejsdevelopers.com

How to Copying Javascript Objects in an efficient way

How to Copying Javascript Objects in an efficient way

Copying Javascript objects can be tricky. Most of the time, we will do shallow copy of an object in javascript.

But, there are few problems associated with that approach. But getting into that topic, we will see what is shallow and deep copy in javsacript.

Shallow vs Deep Copy

In javascript, shallow copy only clones the top level of an object. if an object contains the nested or reference object. it will copy only the reference to it.

Shallow Copy

This is image title

For example, let’s say you have an object like this

let data = {
  "id" : 1,
  "name" : "john",
  "address" : {
    "street" : "Sample",
    "country" : "Earth",
    "Street" : "Madison street"
  }
}

you are copying the object to a new variable using Object.assign

copydata = Object.assign({},data);

After that, if you console log the copydata variable. you will get the output like
This is image title

Now, you are changing the variable data’s object

data.address.street = "Changed Street";

if you console log copydata again, you will get output like,

This is image title

it changes the copied object value too because the copied object will refer to the same object.

To solve this problem, deep copying is used in javascript.

Deep Copy

Meanwhile, deep copying in javascript clones the nested objects too and stores it in the different memory location.

So, changing the original object doesn’t affect the cloned object.
This is image title

Deep Clone in Javascript

it can be achieved using lodash util library in javascript which is one of the popular library in javascript ecosystem.

Install lodash in your machine to use it. After that, there is a method called clonedeep in lodash which is used to achieve the deep copying in javascript.

<iframe height="400px" width="100%" src="https://repl.it/@ganeshmani/shallodeepcopy?lite=true" scrolling="no" frameborder="no" allowtransparency="true" allowfullscreen="true" sandbox="allow-forms allow-pointer-lock allow-popups allow-same-origin allow-scripts allow-modals"></iframe>

Thanks for reading !

How to setting up Node API with Typescript

How to setting up Node API with Typescript

Note: You should have Nodejs installed on your machine.

First thing is to create our project folder and initialize it with npm to generate the package.json file.

Install dependencies

npm i express --save
npm i @types/node @types/express ts-node typescript nodemon --save-dev

Create a tsconfig.json file in the root of your application or run npx tsc --init on your terminal and add the configuration below.

{ 
"compilerOptions":
  {
  "target": "es6",
  "module": "commonjs",
  "allowJs": true,
  "outDir": "./build",
  "rootDir": "./src",
  "esModuleInterop": true
  }
}

Note: More options can be added to the tsconfig.json file.
Find out more here.

Add scripts to package.json file.

"scripts": 
  {
    "dev": "nodemon src/app.ts",
    	"start": "tsc && node build/app"
    }

Create a src directory where our application would be built. Inside the src directory, create an app.ts file.

Inside the app.ts file, add the code below.

import express, { Application, Request, Response, NextFunction } from "express";

const app: Application = express();

app.use(express.json());

app.get("/", (req: Request, res: Response): object => {
    return res.json({ status: "success", message: "Welcome to API Service" });
  }
);

app.use((req: Request, res: Response, next: NextFunction) => {
  const error = new Error("Route Not found");
  next(error);
});

app.use((error: { message: string; status: number }, req: Request, res: Response,next: NextFunction
  ) => {
    res.status(error.status || 500);
    res.json({
      status: "error",
      message: error.message
    });
    next();
  }
);

const PORT: any = process.env.PORT || 3000;

app.listen(PORT, () => console.log(`app listening on port ${PORT}`));

At this point, your project structure should look like the image below.

This is image title

Development

To run the application on the development environment, run the command below

npm run dev

Note: The above command compiles the files found in the src directory in memory.

Production

To run the application on the production environment, run the command below

npm start

Note: The above command compiles the files found in the src directory to a build directory and runs the app.js file in the build directory, as specified above in the start script in our package.json file.

The project used in this article can be found here.

Thanks for reading.

10 Most Popular JavaScript Frameworks 2020 For Developers

10 Most Popular JavaScript Frameworks 2020 For Developers

JavaScript Frameworks is an application framework which is written in javascript. It is a collection of JavaScript code libraries. JavaScript Framework is used to design application. It is very difficult to choose a framework among the most popular JavaScript framework for any project. So it is very important to know that the top javascript framework and features of that particular JavaScript Framework. In this article, we show Top 10 JavaScript frameworks with features and their pros and cons.

1- ANGULAR JS

This is image title

  • Angular JS is an open source framework built over JavaScript. It was built by the developers at Google. This framework was used to overcome the obstacles encountered while working with Single Page applications.

  • AngularJS was born in 2009 as a component of a more immensely colossal commercial product, called GetAngular.

  • Large organizations like PayPal, Freelancer, LinkedIn, Lego, Hopscotch and several others are powering their UIs by AngularJS.

  • Angular makes it easier to work with dynamic rendering with its JSON based processing and rendering capabilities.

  • Angular has been developed with the vision of making it modular, testable and maintainable.
    The latest version of Angular JS is 1.7.8

Features

  • Dependency Injection – js has built-in dependency injection (DI) that helps natural development, understanding, and testing.

  • Data-binding – The two-way data-binding feature saves developers from writing a lot of code. It is the automatic synchronization of data between model and view components.

  • It can be configured in MVC as well as MVW architecture.

  • Services − are a set of code that can be shared by different components of an application.

  • Directives – With this feature, it becomes easy to create custom HTML tags that act like new custom widgets. It can also be used to manipulate DOM attributes.

PROS OF ANGULAR.JS

  • Two-way data binding -AngularJS facilitates faster and easier data binding which doesn’t require a developer to intervene at all.

  • DOM manipulation -the developer saves time and efforts to code, translate and update the DOM elements.

  • Improved server performance -it only serves static files and responds to the API calls.

  • Responsive web – AngularJS makes it possible by letting responsive, fast-loading and seamlessly -navigating websites and apps.

  • Use of directives -AngularJS makes use of directives that keep the scripts and HTML pages mess-free and extremely organized.

CONS OF ANGULAR.JS

  • Difficult learning – you may have to face great difficulty in getting adapted to the framework.

  • The scopes -Quite layered and arranged hierarchically, scopes can be complex entities to handle if it is your first experience with Angular.

  • Inexperience with MVC -If you are completely unfamiliar with the Model-View-Controller architectural patterns, using Angular can be extremely time-consuming.

Blog: Angular Blog

Getting Started: Angular JS

2- NODE.JS

This is image title

  • Node.js is an open source, a cross-platform runtime environment for executing JavaScript code outside of a browser.

  • It is used for building back-end services or APIs and developing server-side and networking applications.

  • It is a platform which is built on Google Chrome’s JavaScript Engine (V8 Engine).

  • Node.js was originally written by Ryan Dahl in 2009.

  • Node.js is developed by Joyent Inc.

  • The latest version of Node.js is 12.2.0.

  • It is used by companies like Uber, PayPal, and Walmart which is a mirror to its global acceptance as a back-end language.

  • The applications built on Node, are written in JavaScript which can be run within the Node.js runtime on OS like Microsoft Windows, Linux as well as MacOS.

FEATURES

  • The applications in Node never buffer any data. This is because the applications output the data in chunks.

  • Node uses single-threaded models which consist of event looping. This event mechanism helps servers to respond in an asynchronous way that makes the servers highly scalable.

  • Same code for client-side and server-side

  • Node technology helps in streaming data from different sources and can be used to proxy some servers.

  • The APIs of the Node’s library is asynchronous which means that the server doesn’t wait for an API to return data; thus rendering the data asynchronously giving a faster response to every request.

PROS OF NODE.JS

  • Share the same piece of code with both server and client side.

  • better efficiency and overall developer productivity

  • it also serves as a marketplace for open source JavaScript tools, which plays an important role in the advance of this technology.

CONS OF NODE.JS

  • Dealing with the relational database is a pain if you are using Node.

  • Node.js is a single-threaded environment, which is often considered a serious drawback of the technology

  • Without diving in depth of JavaScript, if someone starts Node, he may face a conceptual problem.

Getting Started: Node.js 12.2.0

3- REACT

This is image title

  • React is an open-source JavaScript most popular framework which is used by Facebook, Instagram and much more.

  • React is maintained by Facebook, Instagram and a community of individual developers and corporations, and aims to address the challenges encountered in developing single-page applications.

  • React was created by Jordan Walke, a software engineer at Facebook.

  • Latest React version is 16.8.4

  • React is mainly used for the V (view) in the MVC model since the UI can be updated without having to reach out to the server and fetch a new view.

Features

  • Components – React is declarative and component based. The web pages are divided into small components to create UIs.

  • Data binding – One-way data binding along with an application infrastructure called Flux controls. Flux is a pattern that keeps data unidirectional.

  • Maintaining React is easy and straightforward due to its component-based architecture and reusability of the defined components.

  • React can be used on the server-side as well as on client-side.

  • You can use React with other frameworks.

  • Maintaining React is easy and straightforward due to its component-based architecture.

  • JSX – JSX is a javascript extension which indicates that the script needs to be processed and converted to actual javascript.

PROS OF REACT.JS

  • React is the ability to reuse code components of a different level anytime, another meaningful time-saving effect.

  • Virtual DOM in ReactJS makes the user experience better and the developer’s work faster.

  • Stable code – ReactJS allows for direct work with components and uses downward data binding to ensure that changes in child structures don’t affect their parents.

  • An open-source Facebook library – constantly developing and open to the community.

CONS OF REACT.JS

  • JSX as a barrier – Developers and designers complain about JSX’s complexity and consequent steep learning curve.

  • Poor documentation – developers struggle with integrating tools with ReactJS.

Blog: React Js Blog

Getting Started React Js

4- VUE.JS

This is image title

  • Vue.js is a lightweight progressive JS framework which gets a lot of its concepts from ReactJS and AngularJS.

  • Vue.js is a JavaScript front-end framework that was built to organize and simplify web development.

  • Vue was created by Evan You.

  • It is easy to integrate into other applications and languages. For example, Vue.js bundles with Laravel and couples nicely with it to create frontends for Laravel applications.

  • Vue uses an HTML-based templating syntax, allowing developers to write components quickly and easily.

  • Vue has an incredibly small file size, making it easy to include in projects without creating a slowdown.

  • The latest version of Vue.js is 2.6.8

Features

  • Easy to understand and develop

  • Transitions – Vue allows the application of transition effects when items are inserted, removed or updated from the DOM.

  • Reactivity – Vue has a robust reactivity system.

  • It consists of a clear separation between the components and directives.

  • Vue proves to be more flexible and modular front-end development framework.

PROS OF VUE.JS

  • Flexibility -This flexibility makes it easy to switch to Vue because developers who have experience with React, Angular and JS framework would find Vue’s design very familiar.

  • Small Size – it should be noted that the Vue.js ecosystem is also small and fast.

  • The advantage with Vue.js is that it enables the development of large-scale templates.

  • Vue.js useful both for building entire single page applications and for contributing components into existing apps.

  • For a beginner to write their first application, they just have to know some basic Javascript and HTML.

CONS OF VUE.JS

  • Sometimes flexibility can cause some issues for the developers.

  • Language Barrier – A Majority of the users are non-English speaking communities which are perhaps one of the biggest issues with this framework.

  • Vue doesn’t yet have the widespread support of its fellow frameworks as it is not as popular as other frameworks like Angular.js.

Getting Started: Vue.js

5- EMBER

This is image title

  • Ember.js is an open-source client-side JavaScript web application framework predicated on the model-view-controller (MVC) software architectural pattern.

  • Ember’s roots go way back to 2007. Starting its life as the SproutCore MVC framework, pristinely developed by SproutIt and later by Apple, it was forked in 2011 by Yehuda Katz, a core contributor to the popular jQuery and Ruby on Rails projects.

  • It’s used for TinderBox, Netflix, Apple Music, Yahoo!, LinkedIn, PlayStation Now, and Vine.

  • A complete development stack can be formed by using Ember and other important tools.

  • Handlebars layout and Ember’s backend architecture allows writing developers own application-specific HTML tag.

  • Ember has been a highly opinionated framework which was built to be very flexible.

  • The Ember Inspector allows for easy inspection of Ember objects in your browser’s developer tools. This can be used both while developing and while debugging issues.

  • The latest version of Ember is 3.8.0

Features

  • Excellent data library.

  • Ember’sCLI provides standard application structure.

  • Ember works on the Model-view-view model (MVVM) pattern.

  • Inspector tool is useful for debugging applications.

PROS OF EMBER.JS

  • High performance

  • Faster development due to Ember CLI

  • Understandable documentation

  • Two-way data binding

  • Well-organized

  • Own debugging tool (Ember Inspector).

CONS OF EMBER.JS

  • Smaller community and the extensive amount of outdated tutorials on the web

  • Due to a helper function, two-way data binding is more complex.

  • Too big for small projects

  • Complications with processing quick changes

  • Difficult to learn
    Blog: Ember.js

Getting Started: Ember.js

6- BACKBONE.JS

This is image title

  • Backbone.js is a lightweight MVC framework. Born in 2010, it expeditiously grew popular as a lean alternative to cumbersomely hefty, full-featured MVC frameworks such as ExtJS.

  • Backbone.js is developed by Jeremy Ashkenas.

  • This resulted in many accommodations adopting it, including Pinterest, Sony Entertainment Network, Flixster, Airbnb, SoundCloud, and others.

  • Backbone.js gives structure to web applications by providing models with key-value binding and custom events, accumulations with an affluent API of enumerable functions, views with declarative event handling, and connects it all to your subsisting API over a RESTful JSON interface.

  • The latest version is 1.4.0.

FEATURES

  • RESTful JSON interface – Backbone is a framework/ library that has a RESTful JSON interface, based on the Model-view-presenter (MVP) application model.

  • Event-driven communication between views and models prevents the code from being hard to read.

  • Models in Backbone.js can be tied to a back-end since Backbone provides excellent support for RESTful APIs.

  • In case of any changes in a model, the HTML code is automatically updated.

  • It is a simple library that separates UI and business logic.

PROS OF BACKBONE.JS

  • Backbone gives you a lot more control over performance, particularly in mobile scenarios.

  • Easy, fast and lightweight framework so very easy to understand the documentation and codes.

CONS OF BACKBONE.JS

  • The biggest drawback of Backbone is that, instead of providing structure, it provides some basic tools to create structure. So, somewhere you have to depend on developers to decide how to structure the application.

  • To update the view whenever your model changes, and to update the model whenever your view changes, you have to write a lot of boilerplate, because of lack of support for two-way data binding.

Getting Started: Backbone.js

7- POLYMER

This is image title

  • Polymer.js is the open-source JavaScript library for building web applications using Web components.

  • It was the very first library to allow interactive building applications by composing components.

  • Polymer.js is built to leverage the features that are present in the web platform to let developers build components.

  • Polymer.js is being used by YouTube, Google Play Music and Netflix, to name a few.

  • Polymer.js is considered to be one of the best to work with Spring Boot REST resources when compared to other JS frameworks.

  • Version 3.0 of the Polymer library brings web components into the mainstream, embracing JavaScript modules and npm.

  • The latest version is 3.2.0.

FEATURES

  • Speed – It is three times faster in Chrome and four times faster on Safari.

  • Polymer.js is built on top of the web standards API which allows building custom HTML elements

  • Both one-way and two-way data binding is possible with this library.

  • The web component standards are helpful in the creation of usable widgets in web documentation and application.

  • Polymer elements consist of designs and themes which mean prevents developers from modifying complex web page source code to match the designer’s need.

PROS OF POLYMER.JS

  • Quick -The Polymer is a new library which is three times faster on Chrome, four times faster on Safari.

  • Developers use Polymer elements which include design and themes, which means there is no need to modify complex Web page source code to match designer specifications.

  • Polymer.js provides new functionality such as Shadow DOM which enables the encapsulation of CSS.

CONS OF POLYMER.JS

  • Dependency errors and pointing to a different version of dependencies.

  • Downloading of entire library and Polyfills.

  • Lack of server-side rendering.

Blog: Polymer.js Blog

Getting Started: Polymer 3.0

8- METEOR

This is image title

  • Meteor is a full-stack framework, which allows developers to learn one tool, and use it for almost everything in their application.

  • It also makes it an exciting proposition for new developers who are aiming at full-stack positions or projects, as they can get productive faster with Meteor.

  • Meteor uses a front-end JavaScript that runs on the browser and back-end on meteor server within Node.js.
    The latest version of Meteor is 1.8.

  • Meteor is developed by Meteor Development Group.

  • Companies like Mazda, Honeywell, and Qualcomm use Meteor.

FEATURES

  • Meteor provides a full-stack solution for developing and using web applications.

  • Highly scalable and beginner friendly.

  • Easy to set up and start creating projects.

  • It allows using the same code on the front-end as well as the back-end for mobile and web applications.

  • Integrated live reloading allows refreshing only the required DOM elements without reloading the entire page.

PROS OF METEOR.JS

  • Simplicity – Coding is very simple and beginner friendly.

  • Official and community packages are a huge time saver.

  • Velocity is the name of the Meteor’s testing tool. In addition to its core functions, Velocity enables integration with Mocha or Jasmine syntax.

CONS OF METEOR.JS

  • There is a lot of magic going on when working with Meteor, so developers might find themselves limited in some way.

  • Deployment and tool integration is not as simple as some other platforms.

  • Meteor isn’t very suitable for large and complex applications.

Blog: Meteor Blog

Getting Started: Meteor.js

9- MITHRIL.JS

This is image title

  • Mithril is used for creating single-page applications on the client-side.

  • It supports all the browsers like IE9 without the requirement of any polyfills.

  • It is tiny, fast, provides routing and XHR utilities.

  • Mithril has in-built modules for XHR and routing while React needs third parties for the same along with a lot of memory usage.

  • Mithril is known to be pragmatic since it is straightforward to learn components, routing and XHR in less than 15 minutes to start building applications.

  • Mithril is currently being used by companies like Nike and Fitbit and other open source platforms like Liches.

FEATURES

  • It is Flux compatible, robust and un-opinionated

  • Mithril templates are just JavaScript so that developers can test them in any JavaScript engine without a build step.

  • In Mithril.js, components are created with an optional controller and a required view property.

  • Mithril gives hierarchical MVC components, URL routing, safe-by-default templates, customizable data binding.

PROS OF MITHRIL.JS

  • Easy to learn

  • Mithril’s loading times are very fast. This is because it’s templates are compiled first and then served to the browser and because it uses a virtual DOM.

  • Mithril gives to the developer the flexibility to chose the best JavaScript library to use for a specific task.

  • Mithril’s API is pretty small compared to other frameworks.

CONS OF MITHRIL.JS

  • Mithril isn’t recognized much, it often has a head to head competition with other JavaScript frameworks.

Getting Started: Mithril.js 1.1.6

10- AURELIA

This is image title

  • Aurelia is called as the “next-gen UI framework” written in ECMAScript.

  • Aurelia is a collection of open source modern JavaScript modules.

  • Aurelia is a JavaScript client framework for the web, mobile, and desktop that leverages simple conventions to empower your creativity.

  • Aurelia is the only framework that lets you build components with plain, vanilla JavaScript/TypeScript. The framework stays out of your way so your code remains clean and easy to evolve over time.

-Aurelia provides a CLI for generating and building projects, a browser plugin for debugging and a VS Code plugin as well.

FEATURES

  • Routing and UI Composition – Helps in using an advanced client-side router with its pluggable pipeline, child routers, and asynchronous screen activation.

  • HTML Extensible

  • Aurelia integrates with Web Components with no external dependencies.

  • Aurelia supports ES5, ES2015, ES2016 and TypeScript.

  • Testable for ES2015 using DI container. Unit code testing is very simplified.

PROS OF AURELIA.JS

  • The framework itself is directed towards web standards so you will always stay up to date with modern concepts.

  • it is very agile, knowledgeable and willing to help within short notice.

  • It is directed towards the developers’ experience. It saves you lots of time.

  • You can add or remove any tools that the framework offers and you can also add any other tools that aren’t part of the framework.

  • It has a simple structure which makes the framework quicker and easier to learn.

  • It is easy and quick to configure and set it up for use.

CONS OF AURELIA.JS

  • There are no major limitations.

Blog: Aurelia.js

Getting Started: Aurelia.js.

Thanks for reading !

Angular 7 CRUD with Nodejs and MySQL Example

Angular 7 CRUD with Nodejs and MySQL Example

<span class="ql-cursor"></span>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

<pre class="ql-syntax" spellcheck="false">sudo npm install -g @angular/cli </pre>

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:

<pre class="ql-syntax" spellcheck="false">ng new angular7-crud </pre>

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 <a href="http://localhost:4200" title="" target="_blank">http://localhost:4200</a> 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

<pre class="ql-syntax" spellcheck="false">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'); }); </pre>

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

<pre class="ql-syntax" spellcheck="false">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; </pre>


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

<pre class="ql-syntax" spellcheck="false">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 }; </pre>

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:

 

<pre class="ql-syntax" spellcheck="false">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 } </pre>

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

<pre class="ql-syntax" spellcheck="false">// 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 } </pre>

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:

<pre class="ql-syntax" spellcheck="false">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 } </pre>

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

<pre class="ql-syntax" spellcheck="false">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&nbsp;${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&nbsp;${conditions});
dbConfig.getDB().query(delete from article where 1&nbsp;${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&nbsp;${setData}&nbsp;where 1&nbsp;${conditions});
dbConfig.getDB().query(UPDATE article SET&nbsp;${setData}&nbsp;where 1&nbsp;${conditions}, callback);
}
module.exports = {
getArticle : getArticle,
createArticle : createArticle,
deleteArticle : deleteArticle,
updateArticle : updateArticle,
getArticleDetail : getArticleDetail
}
</pre>

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

<pre class="ql-syntax" spellcheck="false"> 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
};
</pre>

3. Create angular component for performing CRUD task of article

<pre class="ql-syntax" spellcheck="false">ng g component article
</pre>

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

<pre class="ql-syntax" spellcheck="false">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)
</pre>

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:

<pre class="ql-syntax" spellcheck="false"> 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 { }
</pre>

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.

<pre class="ql-syntax" spellcheck="false">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);
}
}
</pre>

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:

<pre class="ql-syntax" spellcheck="false">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;
}
}
</pre>

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

<pre class="ql-syntax" spellcheck="false"><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>
</pre>

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 <a href="http://localhost:4200." target="_blank">http://localhost:4200.</a> 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 <a href="https://l.morioh.com/b0a3f595aa?r=https://www.facebook.com/angular4u" title="" target="_blank">Facebook</a> | <a href="https://l.morioh.com/b0a3f595aa?r=https://twitter.com/codek_tv" title="" target="_blank">Twitter</a>

Learn More

☞ <a href="https://l.morioh.com/b0a3f595aa?r=http://learnstartup.net/p/H1jE_tD3l" title="" target="_blank">Angular 8 (formerly Angular 2) - The Complete Guide</a>

☞ <a href="https://l.morioh.com/b0a3f595aa?r=http://learnstartup.net/p/HJigQzgZx" title="" target="_blank">Learn and Understand AngularJS</a>

☞ <a href="https://l.morioh.com/b0a3f595aa?r=http://learnstartup.net/p/ry7Ey9yKW" title="" target="_blank">The Complete Angular Course: Beginner to Advanced</a>

☞ <a href="https://l.morioh.com/b0a3f595aa?r=http://learnstartup.net/p/rkjpGfa5W" title="" target="_blank">Angular Crash Course for Busy Developers</a>

☞ <a href="https://l.morioh.com/b0a3f595aa?r=http://learnstartup.net/p/SkdU19JFZ" title="" target="_blank">Angular Essentials (Angular 2+ with TypeScript)</a>

☞ <a href="https://l.morioh.com/b0a3f595aa?r=http://learnstartup.net/p/B1oHaY8cM" title="" target="_blank">Angular (Full App) with Angular Material, Angularfire & NgRx</a>

☞ <a href="https://l.morioh.com/b0a3f595aa?r=http://learnstartup.net/p/Skf7ILFw3l" title="" target="_blank">Angular & NodeJS - The MEAN Stack Guide</a>



The perfect architecture flow for your next Node.js project

The perfect architecture flow for your next Node.js project

A good start is half the battle, said someone wiser than me. And I can’t think of any quote that would better describe the situation every developer gets into whenever starting a new project. Laying out a project’s structure in a practical way is one of the hardest points of the development process and, indeed, a delicate one.

We can define a path about discussing Node.js technologies, how to choose what front-end framework to use, and now we can try to dig deeper on how to structure our web apps once we have decided on the tech stack to use.

The importance of good architecture

Having a good starting point when it comes to our project architecture is vital for the life of the project itself and how you will be able to tackle changing needs in the future. A bad, messy project architecture often leads to:

  • Unreadable and messy code, making the development process longer and the product itself harder to test

  • Useless repetition, making code harder to maintain and manage

  • Difficulty implementing new features. Since the structure can become a total mess, adding a new feature without messing up existing code can become a real problem

With these points in mind, we can all agree that our project architecture is extremely important, and we can also declare a few points that can help us determine what this architecture must help us do:

  • Achieve clean and readable code

  • Achieve reusable pieces of code across our application

  • Help us to avoid repetitions

  • Make life easier when adding a new feature into our application

Establishing a flow

Now we can discuss what I usually refer to as the application structure flow. The application structure flow is a set of rules and common practices to adopt while developing our applications. These are the results of years of experience working with a technology and understanding what works properly and what doesn’t.

The goal of this article is to create a quick reference guide to establishing the perfect flow structure when developing Node.js applications. Let’s start to define our rules:

Rule #1: Correctly organize our files into folders

Everything has to have its place in our application, and a folder is the perfect place to group common elements. In particular, we want to define a very important separation, which brings us to rule number #2:

Rule #2: Keep a clear separation between the business logic and the API routes

See, frameworks like Express.js are amazing. They provide us with incredible features for managing requests, views, and routes. With such support, it might be tempting for us to put our business logic into our API routes. But this will quickly make them into giant, monolithic blocks that will reveal themselves to be unmanageable, hard to read, and prone to decomposition.

Please also don’t forget about how the testability of our application will decrease, with consequently longer development times. At this point, you might be wondering, “How do we solve this problem, then? Where can I put my business logic in a clear and intelligent way?” The answer is revealed in rule number #3.

Rule #3: Use a service layer

This is the place where all our business logic should live. It’s basically a collection of classes, each with its methods, that will be implementing our app’s core logic. The only part you should ignore in this layer is the one that accesses the database; that should be managed by the data access layer.

Now that we have defined these three initial rules, we can graphically represent the result like this:
This is image title
Separating our business logic from our API routes.

And the subsequent folder structure sending us back to rule #1 can then become:
This is image title

By looking at this last image, we can also establish two other rules when thinking about our structure.

Rule #4: Use a config folder for configuration files

This is image title

Rule #5: Have a scripts folder for long npm scripts

This is image title

Rule #6: Use dependency injection

Node.js is literally packed with amazing features and tools to make our lives easier. However, as we know, working with dependencies can be quite troublesome most of the time due to problems that can arise with testability and code manageability.

There is a solution for that, and it’s called dependency injection.

Dependency injection is a software design pattern in which one or more dependencies (or services) are injected, or passed by reference, into a dependent object.

By using this inside our Node applications, we:

  • Have an easier unit testing process, passing dependencies directly to the modules we would like to use instead of hardcoding them

  • Avoid useless modules coupling, making maintenance much easier

  • Provide a faster git flow. After we defined our interfaces, they will stay like that, so we can avoid any merge conflicts.
    This is image title
    Using Node.js without dependency injection.

Simple but still not very flexible as an approach to our code. What happens if we want to alter this test to use an example database? We should alter our code to adapt it to this new need. Why not pass the database directly as a dependency instead?
This is image title

Rule #7: Use unit testing

Now that we know we have got dependency injection under our belt, we can also implement unit testing for our project. Testing is an incredibly important stage in developing our applications. The whole flow of the project — not just the final result — depends on it since buggy code would slow down the development process and cause other problems.

A common way to test our applications is to test them by units, the goal of which is to isolate a section of code and verify its correctness. When it comes to procedural programming, a unit may be an individual function or procedure. This process is usually performed by the developers who write the code.

Benefits of this approach include:

Improved code quality

Unit testing improves the quality of your code, helping you to identify problems you might have missed before the code goes on to other stages of development. It will expose the edge cases and makes you write better overall code

Bugs are found earlier

Issues here are found at a very early stage. Since the tests are going to be performed by the developer who wrote the code, bugs will be found earlier, and you will be able to avoid the extremely time-consuming process of debugging

Cost reduction

Fewer flaws in the application means less time spent debugging it, and less time spent debugging it means less money spent on the project. Time here is an especially critical factor since this precious unit can now be allocated to develop new features for our product

Rule #8: Use another layer for third-party services calls

Often, in our application, we may want to call a third-party service to retrieve certain data or perform some operations. And still, very often, if we don’t separate this call into another specific layer, we might run into an out-of-control piece of code that has become too big to manage.

A common way to solve this problem is to use the pub/sub pattern. This mechanism is a messaging pattern where we have entities sending messages called publishers, and entities receiving them called subscribers.

Publishers won’t program the messages to be sent directly to specific receivers. Instead, they will categorize published messages into specific classes without knowledge of which subscribers, if any, may be dealing with them.

In a similar way, the subscribers will express interest in dealing with one or more classes and only receive messages that are of interest to them — all without knowledge of which publishers are out there.

The publish-subscribe model enables event-driven architectures and asynchronous parallel processing while improving performance, reliability, and scalability.

Rule #9: Use a linter

This simple tool will help you to perform a faster and overall better development process, helping you to keep an eye on small errors while keeping the entire application code uniform.
This is image title
Example of using a linter.

Rule #10: Use a style guide

Still thinking about how to properly format your code in a consistent way? Why not adapt one of the amazing style guides that Google or Airbnb have provided to us? Reading code will become incredibly easier, and you won’t get frustrated trying to understand how to correctly position that curly brace.
This is image title
Google’s JavaScript style guide.

Rule #11: Always comment your code

Writing a difficult piece of code where it’s difficult to understand what you are doing and, most of all, why? Never forget to comment it. This will become extremely useful for your fellow developers and to your future self, all of whom will be wondering why exactly you did something six months after you first wrote it.

Rule #12: Keep an eye on your file sizes

Files that are too long are extremely hard to manage and maintain. Always keep an eye on your file length, and if they become too long, try to split them into modules packed in a folder as files that are related together.

Rule #13: Always use gzip compression

The server can use gzip compression to reduce file sizes before sending them to a web browser. This will reduce latency and lag.
This is image title
An example of using gzip compression with Express.

Rule #14: Use promises

Using callbacks is the simplest possible mechanism for handling your asynchronous code in JavaScript. However, raw callbacks often sacrifice the application control flow, error handling, and semantics that were so familiar to us when using synchronous code. A solution for that is using promises in Node.js.

Promises bring in more pros than cons by making our code easier to read and test while still providing functional programming semantics together with a better error-handling platform.
This is image title
A basic example of a promise.

Rule #15: Use promises’ error handling support

Finding yourself in a situation where you have an unexpected error or behavior in your app is not at all pleasant, I can guarantee. Errors are impossible to avoid when writing our code. That’s simply part of being human.

Dealing with them is our responsibility, and we should always not only use promises in our applications, but also make use of their error handling support provided by the catch keyword.
This is image title

Conclusion

Creating a Node.js application can be challenging, I hope this set of rules helped you to put yourself in the right direction when establishing what type of architecture you are going to use, and what practices are going to support that architecture.

Originally published by Piero Borrelli at blog.logrocket.com