Understanding *args and **kwargs

Understanding *args and **kwargs in Python 3

Understanding *args

In Python, the single-asterisk form of args can be used as a parameter to send a non-keyworded variable-length argument list to functions. It is worth noting that the asterisk () is the critical element here, as the word args is the established conventional idiom, though the language does not enforce it.

Suppose we create a function to add two integer numbers like this.

def calculate_sum(a, b):
    return a + b

In the code above, we create the function with a and b as arguments, and then when we call the function, we pass two numbers to each argument…

In this case, we will pass number 5 in for a and the integer 6 in for b:

Output

if __name__ == '__main__':
    result = calculate_sum(a=5, b=6)
    print(f"The sum is {result}")

#output: The sum is 11

What is happen if, later on, we decide that we would like to sum the total of three numbers rather than just two? If we try to add a number to the function, as shown below, we’ll receive an error.

if __name__ == '__main__':
    result = calculate_sum(a=5, b=6 , c=8)
print(f"The sum is {result}")
#output : TypeError: calculate_sum() takes 2 positional arguments but 3 were given

So, if you suspect that you may need to use more arguments, later on, you can make use of *args as your parameter instead.
We can essentially create the same function and code that we showed in the first example by removing x and y as function parameters and instead of replacing them with *args as the example below.

def calculate_sum(*args):
    x = 0
    for num in args:
        x += num
    return x

Output

if __name__ == '__main__':
    result_1 = calculate_sum(5, 5, 5)
    result_2 = calculate_sum(5, 5, 5, 5)
    result_3 = calculate_sum(5, 5, 5, 5, 5)
    result_4 = calculate_sum(5, 5, 5, 5, 5, 5)

print(f"The sum is {result_1}")
#output : The sum is 15
print(f"The sum is {result_2}")
#output : The sum is 20
print(f"The sum is {result_3}")
#output : The sum is 25
print(f"The sum is {result_4}")
#output : The sum is 30

Because we used *args to pass a variable argument list to our function, we could pass in as many arguments as we want into the function calls.

With *args we can create more flexible code that accepts a varied amount of non-keyworded arguments within your function.

Understanding **kwargs

In the function below, there are four parameters defined. That is name, surname,  score, and is_active. The function will print out each of these arguments.

def preset_args(name: str, surname: str, score: float, is_active: bool):
    print(f"The value of argument name is : {name}")
    print(f"The value of argument surname is : {surname}")
    print(f"The value of argument score is : {score}")
    print(f"The value of argument is_active is : {is_active}")

When we run the program with the python preset_args.py command, we’ll receive the following output:

if __name__ == '__main__':
    preset_args(name="Christos", surname="Ploutarchou", score=15, is_active=True)
#output : The value of argument name is : Christos
#output : The value of argument surname is : Ploutarchou
#output : The value of argument score is : 15
#output : The value of argument is_active is : True

The double asterisk in kwargs (**kwargs) is used to pass a keyworded variable argument to a function.


Like *args, **kwargs can take however many arguments you would like to supply to it. However, **kwargs differs from *args in that you will need to assign keywords to each value.

First, let’s print out the **kwargs arguments that we pass to a function.

def print_kwargs(**kwargs):
    for key, value in kwargs.items():
        print(f"The key: {key}, The value: {value}")

Let’s run the above function using two different ways and look at the output:


Example One (Pass argument in function)

def print_kwargs(**kwargs):
    for value in kwargs:
        print(value)

Now let’s run the function and set argument as default parameters of the function

if __name__ == '__main__':
    print_kwargs("Christos", "Ploutarchou", 15, True)

Output

Traceback (most recent call last):
  File "/home/christos/PycharmProjects/Tutorials/main.py", line 41, in <module>
    print_kwargs("Christos", "Ploutarchou", 15, True)
TypeError: print_kwargs() takes 0 positional arguments but 4 were given

By running function print_kwargs and pass only value, we get an exception. That happens because we use double asterisk notation (**), then it is required to pass key for each value we give in the function.

Example 2 (Pass keyworded variable arguments)

if __name__ == '__main__':
    print_kwargs(name="Christos", surname="Ploutarchou", score=15, is_active=True)

#output: The value of the argument name is: Christos
#output: The value of argument surname is: Ploutarchou
#output: The value of the argument score is: 15
#output: The value of argument is_active is: True

The function successfully executed without any exception by running function print_kwargs and passing the arguments by set key for each value.

Important Note: The most important thing here is double asterisk notation (**). We can name our kwargs to any value we want, for example, def print_kwargs(**required_arquments).

Conclusion

We can use the particular syntax of *args and **kwargs within a function definition to pass a variable number of arguments to the function.

Creating functions that accept *args and **kwargs are best used in situations where you expect that the number of inputs within the argument list will remain relatively small. The use of *args and **kwargs is primarily to provide readability and convenience but should be done with care.

python dictionary

Stop Using Square Brackets to Get a python Dictionary Values

A python dictionary is an unordered set of keys and values.

That means :

  • Each data point has an identifier (key) and a value.
  • The keys must be unique to that dictionary — no repetitions.
  • The keys have no explicit order — unlike a list.

To define a dictionary, use curly braces and separate each term/definition pair with a comma.

Example

author = {
   "first_name": "Christos",
   "last_name": "Ploutarchou",
   "username": "christos_ploutarchou"
}

The traditional way to get a Dictionary Value

The traditional way to get a value from a dictionary is to use square bracket notation. This syntax nests the name of the key within square brackets, as seen below.

author = {
   "first_name": "Christos",
   "last_name": "Ploutarchou",
   "username": "christos_ploutarchou"
}
print(author['username']) 
#output : christos_ploutarchou 
print(author['surname']) 
#output : KeyError: 'surname'

Notice how trying to reference a term that doesn’t exist causes a KeyError.

These causes cause significant headaches, especially when dealing with unpredictable business data.
While we could wrap our statement in a try/except or if statement, this much care for a dictionary term will quickly heap up.

Example

author = {}
try:
   print(author['username'])
except KeyError as e:
   print(e) # 'username'
if 'username' in author:
   print(author['username'])

If you come from another programming language like JavaScript, you may be tempted to reference a dictionary value using dot notation. That doesn’t work in Python.

author = {
   "first_name": "Christos",
   "last_name": "Ploutarchou",
   "username": "christos_ploutarchou"
}
print(author.username)
# AttributeError: 'dict' object has no attribute 'username'

Start using the .get() Method

When you want to access a dictionary’s value, the safest way to do so is by using the .get() method. This method has two parameters:

  • First (required): the name of the term to be retrieved. This can be a String or a variable, allowing for dynamic term retrieval.
  • Second (optional): the value to be used as a default if the term doesn’t exist.

Example

author = {
   "first_name": "Christos",
   "last_name": "Ploutarchou",
   "username": "christos_ploutarchou"
}
print(author.get('username')) 
#output : christos_ploutarchou 
print(author.get('middle_initial', None)) 
#output : None

When the term has previously been declared, .get() works no differently than a traditional square bracket reference. If the key isn’t defined, a default value is returned that saves you from handling an exception.
This default value can be anything you want, but remember that it’s optional. When no default value is set, the get() method returns None if the key does not exists.

Start using the .setdefault() Method

Sometimes, not only do you want to protect from an undefined key in your dictionary, but you also want your code to self-correct its data structures. The .setdefault() is structured identically to .get(). However, when the key is undefined and returning a default value, it will set the dictionary’s key the default value.

Example

author = {
   "first_name": "Christos",
   "last_name": "Ploutarchou",
   "username": "christos_ploutarchou"
}
print(author.setdefault('username')) 
#output : christos_ploutarchou 
print(author.setdefault('middle_initial', None))
#output : None

In the above example, we see that .setdefault() is the same as square bracket notation or .get() when the key exists.

Additionally, it behaves the same as .get() when the term doesn’t exist, returning the passed default value.
It differs from .get() because the term and definition are now part of the dictionary, as we see below.

author = {
   "first_name": "Christos",
   "last_name": "Ploutarchou",
   "username": "christos_ploutarchou"
}
print(author.setdefault('surname',None)) 
#output : None
print(author)
# output
{
   "first_name": "Christos",
   "last_name": "Ploutarchou",
   "username": "christos_ploutarchou",
   "surname": None

}
"""
Both .get() and .setdefault() are superior techniques when referencing dictionary values. 
When you don’t want to alter the original data, .get() is your choise.
When you want to alter the original data, then just use .setdefault() .
Mastering check data types in Javascript

Mastering check data types in Javascript

This article will help you to check data types in Javascript whether a variable or parameter is a string, number, array, object, function, null & undefined, boolean, regexp, error or date.

Table of contents

How do you check if a variable is a String in Javascript

A string is always a string so this one is easy. Except if called with new (new String) type of will instead return “object”. So to also include those strings instance of can be used.

function isString (value) {
    return typeof value === 'string' || value instanceof String;
}

How do you check if a variable is a Number in Javascript

From type-of more things than just an ordinary number will return “number” like NaN and Infinity. To know if a value really is a number the function isFinite is also required.

function isNumber (value) {
    return typeof value === 'number' && isFinite(value);
}

How do you check if a variable is a Array in Javascript

In JavaScript arrays are not true arrays

In javascript arrays are not true arrays like in java and in other languages. They’re actually objects so typeof will return “object” for them. To know if something’s really an array its constructor can be compared to Array.

function isArray (value) {
return value && typeof value === 'object' && value.constructor === Array;
}

// ES5 actually has a method for this (ie9+)
Array.isArray(value);

How do you check if a variable is a Function in Javascript

Functions are functions so here just typeof is enough.

function isFunction (value) {
    return typeof value === 'function';
}

How do you check if a variable is an Object in Javascript

Many things are objects in javascript. To know if a value is an object that can have properties and be looped through, its constructor can be compared to Object. It doesn’t work for objects created from classes, then the instance of the operator can be used instead.

function isObject (value) {
return value && typeof value === 'object' && value.constructor === Object;
}

How do you check if a variable is a Null & undefined in Javascript

Most times you don’t need to check explicitly for null and undefined since they’re both falsy values. However to do it below functions does the trick.

// Returns if a value is null
function isNull (value) {
    return value === null;
}

// Returns if a value is undefined
function isUndefined (value) {
    return typeof value === 'undefined';
}

How do you check if a variable is a Boolean in Javascript

For booleans typeof is enough since it returns “boolean” for both true and false.

// Returns if a value is a boolean
function isBoolean (value) {
    return typeof value === 'boolean';
}

How do you check if a variable is a RegExp in Javascript

Regexps are objects so the only thing needed to check is if the constructor is Regexp.

// Returns if a value is a regexp
function isRegExp (value) {
    return value && typeof value === 'object' && value.constructor === RegExp;
}

How do you check if a variable is an Error in Javascript

Errors in javascript are the same as “exceptions” in many other programming languages. They come in a couple of different forms like for instance Error, TypeError, and RangeError. An instanceof statement is enough for them all, but just to be extra sure we also check for the “message” property that errors have.

// Returns if value is an error object
function isError (value) {
return value instanceof Error && typeof value.message !== 'undefined';
}

How do you check if a variable is a Date in Javascript

Date isn’t really a data type in Javascript. But to know if something’s a Date object it can be checked with instanceof.

// Returns if value is a date object
function isDate (value) {
    return value instanceof Date;
}

How do you check if a variable is a Symbol in Javascript

In ES6 the new datatype Symbol was added. Nicely enough typeof returns “symbol” for it so no more logic is required.

// Returns if a Symbol
function isSymbol (value) {
return typeof value === 'symbol';
}
Best Way To Validate Email In Javascript

Best Way To Validate Email In Javascript

Javascript is one of the most trending programming language these days. Be it frontend development or backend development, Javascript used widely in almost every field of web development.

While the development of any websites or applications using the Javascript, we have to create a contact form, signup form, sign in form, or any other type of forms where we need users’ email.

It is very important to validate the input fields before doing any further action on this. And email validation is a must to do thing in any type of form building.

Here, we are not going to debate about what is the email and which one is a valid or invalid email.

So without wasting any further time, let’s see how to validate email in Javascript.

Different Methods To validate Email In Javascript

There are many ways to validate the email depending upon the requirement.

  • Using the regex expression
  • Using any third party library
  • Using HTML in-built email validation property

Here, we are going to use the simple regex expression for validating the email.

Rules That Email Validation Should Follow

Before writing the regex, we first know what is the basic rule that email validation should follow?

Mainly an email address consists of two-part, local part and domain part.

The local-part contains the following thing

  • any alphanumeric character: a-zA-Z0-9
  • a dot ((.), if it’s not the first or last character
  • punctuation: “(),:;<>@[\]
  • special characters: !#$%&’*+-/=?^_{|}~

And the domain part contains the following

  • any alphanumeric character: a-zA-Z0-9
  • the hyphen (-), if it’s not the first or last character. It can be repeated

Regular Expression To Validate Email In Javascript

There is no universal regular expression to validate email, Everyone is using a different set of regex in their code to validate the email.

Before using any regex in your code, you first validate it by trying on so some valid and invalid email address.

/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/

Above is the regex which can validate the 99.9% of the email address.

I know, it is not the simple regex to understand. Some regex expert writes this and it spread all over the internet now.

You can check this regex by trying any online regular expression testing tool. For my testing, I prefer to use regexr website.

Javascript Code To Validate Email

const validateEmail = (email)  => {
    const re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    return re.test(email.toLowerCase());
}

Above is the simple javascript arrow function which is used to validate any email. Code is very simple to understand, here we use the regular expression to compare it with the provided email id after converting it into the lowercase.

Conclusion

This is all above the validation email in javascript using the regex. Although the regex which is used in this article is not easy to understand in the first go.

Note : If you have any doubts or suggestion then do comment in the comment box and if you like this article then share it.

rest-api-with-express-sequilize-mysql

How To Build Simple Node.js Rest APIs with Express, Sequelize & MySQL

We’ll be start to build a Node.js Rest API with Express, Sequelize & MySQL. Here we’ll use Sequelize for interacting with the MySQL instance.

Required applications

  • Docker is a set of platform as a service product that uses OS-level virtualization to deliver software in packages called containers. Containers are isolated from one another and bundle their own software, libraries and configuration files; they can communicate with each other through well-defined channels.
  • Node.js is a platform built on Chrome’s JavaScript runtime for easily building fast and scalable network applications. Node.js is an open-source, cross-platform runtime environment for developing server-side and networking applications.
  • ExpressJS is one of the most popular web frameworks for node.js. It is built on top of node.js HTTP module and adds support for routing, middleware, view system, etc. It is very simple and minimal, unlike other frameworks that try to do way too much, thereby reducing the flexibility for developers to have their own design choices.
  • Sequelize is a promise-based Node.js ORM for Postgres, MySQL, MariaDB, SQLite, and Microsoft SQL Server. It features solid transaction support, relations, eager and lazy loading, read replication and more.
  • CORS is a node.js package for providing a Connect/Express middleware that can be used to enable CORS with various options
  • body-parser Parse incoming request bodies in a middleware before your handlers, available under the req.body property.
  • Postman is an API(application programming interface) development tool that helps to build, test and modify APIs.It has the ability to make various types of HTTP requests(GET, POST, PUT, PATCH, etc.).

Node.js Rest CRUD API overview

We will build Rest Apis that can create, retrieve, update, delete and find posts by title.

First, we start with an Express web server. Next, we add configuration for MySQL database, create Post a model with Sequelize, write the controller. Then we define routes for handling all CRUD operations (including custom finder).

The following table shows overview of the Rest APIs that will be exported

MethodsUrlsActions
GETapi/posts/allGet all Posts
GETapi/posts/:idGet post by id
POSTapi/posts/createCreate a new post
PUTapi/posts/update/:idUpdate post by id
DELETEapi/posts/delete/:idDelete post by id
DELETEapi/posts/deleteallsDelete all posts
GETapi/posts/publishedGet all published posts
GETapi/posts?title=’test’Get all posts which title contains 'test'
GETapi/posts/publisher?name=christosGet All posts where publisher name is  'christos'

This is our project structure:

rest api project structyre

Now let’s start Creating Node.js App

First, we create a folder:

$ mkdir node_rest_api_with_mysql
$ cd node_rest_api_with_mysql

Next, we initialise the Node.js App with a package.json file:

npm init

name: (nodejs-express-sequelize-mysql) 
version: (1.0.0) 
description: Node.js Rest Apis with Express, Sequelize & MySQL.
entry point: (index.js) server.js
test command: 
git repository: 
keywords: nodejs, express, sequelize, mysql, rest, api, docker
author: Christos Ploutarchou
license: (ISC)

Is this ok? (yes) yes

If your already have MySQL installed on you PC you can ignore following Steps

Next, need to install docker for mysql and phpMyAdmin.

  1. Install Docker (Learn more about docker installation here)
  2. Enter on the project root directory 
  3. Up the compose
docker-compose up -d
  • Access phpmyadmin
your_ip:8183
Server: mysql
Username: root/root
Password: root/pass
  • Access mysql on terminal
 docker exec -it mysql_container_name mysql -u root -p

Docker phpmyadmin ENV

PMA_ARBITRARY when set to 1 connection to the arbitrary server will be allowed
PPMA_HOST define address/host name of the MySQL server
PMA_PORT define port of the MySQL server
  • If you need more information about phpmyadmin image. READ HERE
  • If you need more information about mysql image. READ HERE

We need also to install necessary modules: expresssequelizemysql2 and body-parser on our project.

Run the command:

npm install express body-parser cors  sequelize mysql2 --save

When installation finish package.json file should look like this:

{
  "name": "node_rest_api_with_mysql",
  "version": "1.0.0",
  "description": "Node.js Rest Api with Express, Sequelize, MySQL & phpMyAdmin .",
  "main": "server.js",
  "scripts": {
    "start": "nodemon server.js"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/cploutarchou/node_rest_api_with_mysql.git"
  },
  "keywords": [
    "node",
    "rest-api",
    "tutorial",
    "mysql",
    "phpMyAdmin",
    "docker",
    "node.js",
    "sequilize"
  ],
  "author": "Christos Ploutarchou",
  "license": "ISC",
  "bugs": {
    "url": "https://github.com/cploutarchou/node_rest_api_with_mysql/issues"
  },
  "homepage": "https://github.com/cploutarchou/node_rest_api_with_mysql#readme",
  "dependencies": {
    "body-parser": "^1.19.0",
    "cors": "^2.8.5",
    "express": "^4.17.1",
    "mysql2": "^2.1.0",
    "sequelize": "^5.21.5"
  },
  "devDependencies": {
    "nodemon": "^2.0.2"
  }
}

Setup Express web server

In our root directory need to create a new server.js file:

const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const server = express();
const db = require("./models");
const corsSettings = {
  originL: "http://localhost:8081"
};

const api = require("./routes/index");
server.use(cors(corsSettings));

// Parse request of content-type - application/json
server.use(bodyParser.json());

// parse requests of content-type -application/x-www-form-urlencoded
server.use(bodyParser.urlencoded({ extended: true }));

create a simple route
server.get("/", (_req, res) => {
   res.json({ message: "Welcome to node.js rest api application. Created for learning purposes by Christos Ploutarchou" });
});

// set listening ports for request
const port = process.env.PORT || 8080;

server.listen(port, () => {
  console.log("Server running on port : " + port );
});

What we are doing here:
– import expressbody-parser and cors modules:

  • Express is for building the Rest apis.
  • body-parser helps to parse the request and create the req.body object.
  • cors provides Express middleware to enable CORS with various options.

– create an Express app, then add body-parser and cors middlewares using app.use() method. Notice that we set origin: http://localhost:8081.
– define a GET route which is simple for test.
– listen on port 8080 for incoming requests.

Now let’s run the app by running the following command : node server.js.
Open your browser with URL http://localhost:8080/, you will see:

Yes Correct, the first step is done. We’re gonna work with Sequelize in the next section.

Configure MySQL database & Sequelize

In the root folder, we create a separate config folder for configuration with db.config.js file like this:

Note: If you don’t user project docker compose, Then need to update database info with your local environment credentials and info.

module.exports = {
  HOST: "localhost",
  USER: "root",
  PASSWORD: "pass",
  DB: "restapi",
  dialect: "mysql",
  pool: {
    max: 10,
    min: 0,
    acquire: 30000,
    idle: 50000
  }
};

The first five parameters are for MySQL connection.
pool is optional, it will be used for Sequelize connection pool configuration:

  • max: maximum number of connection in pool
  • min: minimum number of connection in pool
  • idle: maximum time, in milliseconds, that a connection can be idle before being released
  • acquire: maximum time, in milliseconds, that pool will try to get connection before throwing error

For more information, you can visit API Reference for the Sequelize constructor.

Initialize Sequelize

We’re gonna initialise Sequelize in app/models folder that will contain model in the next step.

Now create app/models/index.js with the following code:

const dbConfig = require("../config/db.config");
const Sequelize = require("sequelize");
const database = new Sequelize(dbConfig.DB, dbConfig.USER, dbConfig.PASSWORD, {
  host: dbConfig.HOST,
  dialect: dbConfig.dialect,
  operatorsAliases: false,
  pool: {
    max: dbConfig.pool.max,
    min: dbConfig.pool.min,
    acquire: dbConfig.pool.acquire,
    idle: dbConfig.pool.idle
  }
});

const db = {};
db.Sequelize = Sequelize;
db.databaseConf = database;
db.posts = require("./Sequelize.model")(database, Sequelize);
module.exports = db;

Don’t forget to call sync() method in server.js:

const db = require("./models");
db.databaseConf.sync();

After that your server.js file must look like below:

const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const server = express();
const db = require("./models");
const corsSettings = {
  originL: "http://localhost:8081"
};

const api = require("./routes/index");
server.use(cors(corsSettings));

// Parse request of content-type - application/json
server.use(bodyParser.json());

// parse requests of content-type -application/x-www-form-urlencoded
server.use(bodyParser.urlencoded({ extended: true }));

create a simple route
server.get("/", (_req, res) => {
   res.json({ message: "Welcome to node.js rest api application. Created for learning purposes by Christos Ploutarchou" });
});

// set listening ports for request
const port = process.env.PORT || 8080;

server.listen(port, () => {
  console.log("Server running on port : " + port );
});
db.databaseConf.sync();

Define the Sequelize Model

In models folder, create Sequelize.model.js  file like this:

module.exports = (database, Sequelize) => {
  return database.define("restTutorial", {
    title: {
      type: Sequelize.STRING
    },
    description: {
      type: Sequelize.TEXT
    },
    published: {
      type: Sequelize.BOOLEAN
    },
    publisher: {
      type: Sequelize.STRING
    }
  });
};

This Sequelize Model represents restTutorials table in MySQL database. These columns will be generated automatically: idtitledescriptionpublishedcreatedAtupdatedAt.

After initializing Sequelize, we don’t need to write CRUD functions, Sequelize supports all of them:

  • Create a new post : create(object)
  • Get all posts: findAll()
  • Update a post by id: update(data, where: { id: id })
  • Delete a post : destroy(where: { id: id })
  • Delete all posts: destroy(where: {})
  • Get all post by title: findAll({ where: { title: ... } })
  • Get all post by publisher name: findAll({ where: { publisher: ... } })

These functions will be use it on our Controller.

Create the Controller

Inside app/controllers folder, let’s create Post.js with these CRUD functions:

  • create
  • findAll
  • findOne
  • update
  • delete
  • deleteAll
  • findAllPublished
  • findByPublisherName
const db = require('../models')
const postObj = db.posts
const Op = db.Sequelize.Op

// Create and save new Post
exports.create = (request, result) => {
}

// Save Post object to db
postObj.create(post).then(data => {

}

// Retrieve all Post (Receive data with condition).
exports.getAllPosts = (request, result) => {

}

// Get Post object by ID
exports.getPostByID = (request, result) => {

}
// Update a Post object by the id
exports.updatePostByID = (request, result) => {

}

// Delete Post object by ID
exports.deletePostByID = (request, result) => {

}

// Delete All Posts objects from database
exports.deleteAllPosts = (request, result) => {

}

// Get all published Post
exports.getAllPublishedPosts = (request, result) => {

}

// Get all published Post by Publisher Name
exports.getAllPostsByPublisherName = (request, result) => {

}

// Get all published post by Title
exports.getPostByTitle = (request, result) => {

}

Now Let’s implement these functions.

Create a new post object

// Create and save new Post
exports.create = (request, result) => {
  if (!request.body.title) {
    result.status(400).send({
      message: "Content cannot be empty"
    });
  }

  // Create a Post object
  const post = {
    title: request.body.title,
    description: request.body.description,
    published: request.body.published ? request.body.published : false,
    publisher: request.body.publisher ? request.body.publisher : false
  };

  // Save Post object to db
  postObj.create(post).then(data => {
    result.send(data);
  }).catch(err => {
    result.status(500).send({
      message: err.message || "Some error occurred while saving."
    });
  });
};

Get all objects (By post title)

// Get all published post by Title
exports.getPostByTitle = (request, result) => {
  const title = request.query.title;
  postObj.findAll({
    where: {
      publisher: { [Op.like]: `%${title}%` },
      published: true
    }
  }).then(data => {
    result.send(data);
  }).catch(err => {
    result.status(500).send({
      message: err.message || "Something going wrong. Unable to retrieve data!"
    });
  });
};

On that function we use request.query.title to get query string from the Request and consider it as condition for findAll() method.

Get single post object (By post ID)

// Get Post object by ID
exports.getPostByID = (request, result) => {
  const paramID = request.params.id;
  console.log(paramID);
  console.log(paramID);
  postObj.findAll({
    where: { id: paramID }
  }).then(data => {
    result.send(data);
  }).catch(err => {
    result.status(500).send({
      message: err.message || `Some error occurred while retrieving data with id : ${paramID}`
    });
  });
};

Update a Post object by the id

// Update a Post object by the id
exports.updatePostByID = (request, result) => {
  const id = request.params.id;
  postObj.update(request.body, {
    where: { id: id }
  }).then(num => {
    if (num === 1) {
      result.send({
        message: "Post object successfully updated."
      });
    } else {
      result.send({
        message: `Cannot update Post object with id=${id}!`
      });
    }
  }).catch(err => {
    result.status(500).send({
      message: err.message || `Error while updating Post object with id=${id}!`
    });
  });
};

Delete Post object by ID

// Delete Post object by ID
exports.deletePostByID = (request, result) => {
  const id = request.params.id;
  postObj.destroy({
    where: { id: id }
  }).then(num => {
    if (num === 1) {
      result.send({
        message: "Post object successfully deleted."
      });
    } else {
      result.send({
        message: `Cannot delete Post object with id=${id}!`
      });
    }
  }).catch(err => {
    result.status(500).send({
      message: err.message || `Cannot delete Post object with id=${id}!`
    });
  });
};

Delete All Posts objects from database

// Delete All Posts objects from database
exports.deleteAllPosts = (request, result) => {
  postObj.destroy({
    where: {},
    truncate: false
  }).then(nums => {
    result.send({
      message: `${nums} Post objects was deleted successfully!`
    });
  }).catch(err => {
    result.status(500).send({
      message: err.message || "Cannot delete Post objects. Something going wrong}!"
    });
  });
};

Get all published Posts objects from database

// Get all published Post
exports.getAllPublishedPosts = (request, result) => {
  postObj.findAll({
    where: { published: true }
  }).then(data => {
    result.send(data);
  }).catch(err => {
    result.status(500).send({
      message: err.message || "Something going wrong. Unable to retrieve data!"
    });
  });
};

Get all published Posts objects from database

exports.getAllPosts = (request, result) => {
  postObj.findAll()
    .then(data => {
      result.send(data);
    }).catch(err => {
      result.status(500).send({
        message: err.message || "Some error occurred while retrieving data."
      });
    });
};

Get all Posts by Publisher Name

// Get all published Post by Publisher Name
exports.getAllPostsByPublisherName = (request, result) => {
  const name = request.params.name;
  const condition = name ? { publisher: { [Op.like]: `%${name}%` } } : null;
  postObj.findAll({ where: condition }).then(data => {
    result.send(data);
  }).catch(err => {
    result.status(500).send({
      message: err.message || "Something going wrong. Unable to retrieve data!"
    });
  });
};

Define Routes

When a client sends request for an endpoint using HTTP request (GET, POST, PUT, DELETE), we need to determine how the server will reponse by setting up the routes.

Let’s now create a a index.js file inside routes/ folder with content like this:

const post = require("../controllers/Post");
const express = require("express");
const router = express.Router();
// Create New Post
router.post("/api/posts/create", post.create);
// // Retrieve all posts
router.get("/api/posts/all", post.getAllPosts);
// Retrieve all Published posts
router.get("/api/posts/published", post.getAllPublishedPosts);
// Retrieve all Published posts by Publisher Name
router.get("/api/posts/publisher", post.getAllPostsByPublisherName);
// Retrieve all posts by title
router.get("/api/posts", post.getPostByTitle);
// Retrieve post by ID
router.get("/api/posts/:id", post.getPostByID);
// // Update post by ID
router.put("/api/post/update/:id", post.updatePostByID);
// // Delete post by ID
router.delete("/api/post/delete/:id", post.deletePostByID);
// Delete all posts
router.delete("/api/posts/deleteAll", post.deleteAllPosts);

module.exports = router;

You can see that we use a controller from ..controllers/Post.

We also need to include routes in server.js (right before app.listen()):

const api = require("./routes/index");

server.use("/", api);

After that update our server.js file must look like:

const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const server = express();
const db = require("./models");
const corsSettings = {
  originL: "http://localhost:8081"
};

const api = require("./routes/index");
server.use(cors(corsSettings));
// Parse request of content-type - application/json
server.use(bodyParser.json());
// parse requests of content-type -application/x-www-form-urlencoded
server.use(bodyParser.urlencoded({ extended: true }));

server.use("/", api);
// set listening ports for request
const port = process.env.PORT || 80;

server.listen(port, () => {
  console.log(`Server running on port : ${port}`);
});
// Run following function if you want drop existing tables and re-sync database
// db.dropRestApiTable();
db.databaseConf.sync();

Note : In development, you may need to drop existing tables and re-sync database. So let’s create a new function on models/index.js to apply that.

Add following function on index.js

db.dropRestApiTable = () => {
  db.databaseConf.sync({ force: true }).then(() => {
    console.log("restTutorial table just dropped and db re-synced.");
  });
};

You can call that function on server.js file when you want drop existing table:

db.dropRestApiTable();

Test the APIs

Run our Node.js application with command: node server.js.

Server running on port : 80
Executing (default): CREATE TABLE IF NOT EXISTS restTutorials (id INTEGER NOT NULL auto_increment , title VARCHAR(255), description TEXT, published TINYINT(1), publisher VARCHAR(255), createdAt DATETIME NOT NULL, updatedAt DATETIME NOT NULL, PRIMARY KEY (id)) ENGINE=InnoDB;
Executing (default): SHOW INDEX FROM restTutorials

Using Postman, we’re gonna test all the Apis above.

1. Create a new posts using /api/posts/create Api

Below you can see a sample of our post request:

{
    "title": "JS Tutorials : Part 1",
    "description": "Node.js Rest APIs with Express, Sequelize & MySQL Part 1",
    "published": true,
    "publisher": "Christos Ploutarchou"
}

When we send post request if data stored on db we must get STATUS: 200 OK

Note: If you run MySQL using docker-compose you can access phpMyAdmin on localhost:8183 using following credentials username: root | password: pass

After creating some new Posts, you can check MySQL table by running following query on phpMyAdmin

select * from posts;

Your output must look something like image below:

2 . Retrieve all Posts using GET /api/posts/all Api

You should get something like image below:

Get all posts
Get All posts

3 . Retrieve all Posts using GET /api/posts/:id Api

Get Post By ID
Get Post By ID

4 . Update a Post using PUT /api/post/update/:id Api

Update Post by ID
Update Post by ID

5 . Find all Posts which contain word ‘tutorials’ using GET /api/posts?title=tutorial Api

Get post by title
Get post by title

6 . Find all Posts by Publisher Name using GET /api/posts/publisher/?name=Christos Api

get all post by publisher name
Get all post by publisher name

7. Find all published posts using GET /api/posts/published Api

Get all published posts

8. Delete a post using DELETE /api/posts/delete/:id Api

Delete post by post ID

9. Delete all posts using DELETE /api/posts/deleteAll Api

Delete all posts
Delete all posts

You can download a complete copy of the project via my GitHub repository Click Here. (Please leave a star if you like my project)

How to iterate over Javascript object properties

How to iterate over Javascript object properties

Here some very common tasks how to iterating over an JavaScript object properties

If you have an object, you can’t just iterate it using map()forEach() or a for..of loop.

You will get the following errors:

const items = {
  'date': new Date(),
  'number': 2,
  'sampleString': 'test'
}

map() function will give you TypeError: items.map is not a function:

items.map(item => {})

forEach()  function will give you TypeError: items.forEach is not a function:

items.forEach(item => {})

for..of  will give you TypeError: items is not iterable:

for (const item of items) {}

So, what can you do to iterate?

for (const item in items) {
  console.log(item)
}

You can also do ti by call Object.entries() function to generate an array with all its enumerable properties, and loop through that, using any of the above methods:

Object.entries(items).map(item => {
  console.log(item)
})

Object.entries(items).forEach(item => {
  console.log(item)
})

for (const item of Object.entries(items)) {
  console.log(item)
}
Map() vs. forEach()

Map vs forEach in JavaScript – What Is the Difference?

One of my most loved functions in JavaScript might be map() and forEach. They both started to exist since ECMAScript 5, ores5 in short.

On that post, I am going to talk about the main difference between each and show you some examples of their usages.

Basically, looping over an object in JavaScript counts on whether or not the object is an iterable. Arrays are iterable by default.

map() and forEach() are included in the Array.prototype, so we don’t need to think about iterable. If you want to study further, I recommend you check out what an iterable object is in JavaScript!

What Are map() and forEach()?

map and forEach are helper methods in array to loop over an array easily. We used to loop over an array, like below, without any helper functions.

let array = ['1', '2', '3'];
for (let i = 0; i < array.length; i += 1) {
  console.log(Number(array[i]));
}
// >>>>>>>>>>>>>return values:
// 1
// 2
// 3

The for loop has been with us since the very beginning of the JavaScript era. It takes 3 expressions: the initial value, condition, and final expression.

This is a classic way of looping an array. Since ECMAScript 5, new functions have appeared to make our file more easier.

1.map()

map does exactly the same thing as what the for loop does, except that map creates a new array with the result of calling a provided function on every element in the calling array.

It takes two parameters: a callback function that will be invoked later when map or forEach is called, and the context variable called this argument that a callback function will use when it’s invoked.

const arr = ['1', '2', '3'];
// callback function takes 3 parameters
// the current value of an array as the first parameter
// the position of the current value in an array as the second parameter
// the original source array as the third parameter
const example = (str, i, res) => {
  console.log(`${i}: ${Number(str)} / ${res}`);
};
arr.map(example);
// >>>>>>>>>>>>>return values:
// 0: 1 / 1,2,3
// 1: 2 / 1,2,3
// 2: 3 / 1,2,3

The callback function can be used as below.

arr.map((example) => { console.log(Number(example)); })

The result of map is not equal to the original array.

const arr = [1];
const new_arr = arr.map(d => d);
arr === new_arr; // false

You can also pass the object to the map as this argument.

const obj = { name: 'Christos' };

[1].map(function() {
  // { name: 'Christos' }
  console.dir(this);
}, obj);

[1].map(() => {
  console.dir(this);
}, obj);

The object obj became the thisArg for map. But the arrow callback function can’t get obj as its thisArg.

This is because arrow functions work differently from normal functions. Visit this article to see what’s different between arrow functions and normal functions.

2.forEach()

forEach is another looping function for an array but there’s a difference between map and forEach in use. There are two parameters that map and forEach can take — a callback function and this  argument which they use as their this.

const arr = ['1', '2', '3'];
// callback function takes 3 parameters
// the current value of an array as the first parameter
// the position of the current value in an array as the second parameter
// the original source array as the third parameter
const example = (str, i, origin) => {
  console.log(`${i}: ${Number(str)} / ${origin}`);
};
arr.forEach(example);
// >>>>>>>>>>>>>return values:
// 0: 1 / 1,2,3
// 1: 2 / 1,2,3
// 2: 3 / 1,2,3

What’s different?

[1,2,3].map(d => d + 1); // [2, 3, 4];
[1,2,3].forEach(d => d + 1); // undefined;

forEach doesn’t ensure the immutability of an array if you change values inside an array. This method only ensures immutability when you don’t touch any values inside.

[{a: 1, b: 2}, {a: 10, b: 20}].forEach((obj) => obj.a += 1);
// [{a: 2, b: 2}, {a: 11, b: 21}]
// The array output has been changed!

So When to Use map() and forEach()?

Since the main difference between them is whether or not there is a return value, you would want to use map to make a new array and use forEach just to map over the array.

Here an example:

const people = [
  { name: 'Christos', whatCanDo: 'canDo1' },
  { name: 'George', whatCanDo: 'canDo2' },
  { name: 'John', whatCanDo: 'canDo3' }
];

 makeWorkers(people) => {
  return people.map((person) => {
    const { name, whatCanDo } = person;
    return <li key={name}>My name is {name}, I can do {whatCanDo}</li>
  });
}

<ul>makeWorkers(people)</ul>

On the other hand, forEach is useful when you want to do something with the data without creating a new array. By the way, the example could be refactored using filter.

subjects.filter(subject => mySubjectId.includes(subject.id)).length;

To summarise, I recommend you use map when creating a new array that you will use, and use forEach when you don’t need to make a new array, but rather, there’s something you want to do with the data.

Speed Comparison

Some posts mentioned map is faster than forEach. So, I was curious if it’s for real. I found this comparison result:

source : https://jsperf.com/foreach-v-map

The code looks very similar but the results are the opposite. Some tests said forEach is faster and some said map is faster.

Maybe you are telling yourself that map/forEach is faster than the other, and you might be right. I’m not sure, honestly. I think readability is much more important than the speed between map and forEach when it comes to modern web development.

But one thing’s for sure — both of them are slower than the built-in feature of JavaScript, for loop.

Conclusion

map and forEach are handy functions for looping over an iterable object and might beautify your code and give you more readability.

But one really important keynote to keep in mind is to understand what each does and when to use each.

map would be good when you want to make a new array that does not affect the original array, and forEach would be nicer when you just want to map over an array.

Resources:

es6 arrow function

When (and why) you should use ES6 arrow functions — and when you shouldn’t

Arrow functions are undoubtedly one of the more popular features of ES6. They introduced a new way of writing concise functions.

Here is a function how is written in ES5 syntax:

function calculateAge(birthYear) {  
return 2020- birthYear
}

calculateAge(1984);  // 36

Now, here is the same function expressed as an arrow function:

const calculateAge = birthYear => 2020 - birthYear

calculateAge(1984);  // 36

It’s much shorter! We are able to omit the curly braces and the return statement due to implicit returns (but only if there is no block — more on this below).

It is important to understand how the arrow function behaves differently compared to the regular ES5 functions.

Variations

One thing you will quickly notice is the variety of syntaxes available in arrow functions. Let’s run through some of the common ones:

1. No parameters

If there are no parameters, you can place empty parentheses before = .

() => 36

In fact, you don’t even need the parentheses!

_ => 36

2. Single parameter

With these functions, parentheses are optional:

x => 36  || (x) => 36

3. Multiple parameters

Parentheses are required for these functions:

(x, y) => 36

4. Statements (as opposed to expressions)

In its most basic form, a function expression produces a value, while a function statement performs an action.

With the arrow function, it is important to remember that statements need to have curly braces. Once the curly braces are present, you always need to write return as well.

Here is an example of the arrow function used with an if statement:

let is_friend = (param) => {
  if (param === true) {
    return 'Can Join chat';
  } else {
    return 'No access on chat channel';
  }
}

5. “Block body”

If your function is in a block, you must also use the explicit return statement:

let addValues = (x, y) => {
  return x + y
}

6. Object literals

If you are returning an object literal, it needs to be wrapped in parentheses. This forces the interpreter to evaluate what is inside the parentheses, and the object literal is returned.

x =>({ y: x })

7. Syntactically anonymous

It is important to note that arrow functions are anonymous, which means that they are not named.

This anonymity creates some issues:

  1. Harder to debug

When you get an error, you will not be able to trace the name of the function or the exact line number where it occurred.

2. No self-referencing

If your function needs to have a self-reference at any point (e.g. recursion, an event handler that needs to unbind), it will not work.

Main benefit: No binding of ‘this’

In classic function expressions, the this keyword is bound to different values based on the context in which it is called. With arrow functions, however, this are lexically bound. It means that it uses this from the code that contains the arrow function.

For example, look at the setTimeout function below:

// ES5
var obj = {
  id: 65,
  counter: function counter() {
    setTimeout(function() {
      console.log(this.id);
    }.bind(this), 850);
  }
};

In the ES5 example, .bind(this) is required to help pass the this context into the function. Otherwise, by default this would be undefined.

// ES6
let obj = {
  id: 65,
  counter: function counter() {
    setTimeout(() => {
      console.log(this.id);
    }, 850);
  }
};

ES6 arrow functions can’t be bound to a this keyword, so it will lexically go up a scope, and use the value of this in the scope in which it was defined.

When you should not use Arrow Functions

After learning a little more about arrow functions, I hope you understand that they do not replace regular functions.

Here are some instances where you probably wouldn’t want to use them:

  1. Object methods

When you call cat.jumps, the number of lives does not decrease. It is because this is not bound to anything, and will inherit the value of this from its parent scope.

let player = {
  lives: 3,
  jumps: () => {
    this.lives--;
  }
}

2. Callback functions with dynamic context

If you need your context to be dynamic, arrow functions are not the right choice. Take a look at this event handler below:

let button = document.getElementById('press');
button.addEventListener('click', () => {
  this.classList.toggle('on');
});

If we click the button, we would get a TypeError. It is because this is not bound to the button, but instead bound to its parent scope.

3. When it makes your code less readable

It is worth taking into consideration the variety of syntax we covered earlier. With regular functions, people know what to expect. With arrow functions, it may be hard to decipher what you are looking at straightaway.

When you should use them

Arrow functions shine best with anything that requires this to be bound to the context, and not the function itself.

Despite the fact that they are anonymous, I also like using them with methods such as map and reduce, because I think it makes my code more readable. To me, the pros outweigh the cons.

node-js-wallpaper

Some Useful Node.js Internal Modules

1. OS

JavaScript in Web browser cannot get the information about Operating System (OS) but node.js can

const os = require('os');

console.log('operating system information -------------');
console.log('os.arch()', os.arch()); // x64
console.log('os.platform():', os.platform()); // win32
console.log('os.type():', os.type()); // Windows_NT
console.log('os.uptime():', os.uptime()); // 53354.5432871
console.log('os.hostname():', os.hostname()); // DESKTOP-CPLOU
console.log('os.release():', os.release()); // 10.0.15063

console.log('path -------------');
console.log('os.homedir():', os.homedir()); // C:\Users\cplou
console.log('os.tmpdir()', os.tmpdir()); // C:\Users\cplou\AppData\Local\Temp

console.log('memory information -------------');
console.log('os.freemem():', os.freemem()); // 9122930688
console.log('os.totalmem():', os.totalmem()); // 17060175872
  • os.type() : Shows the Operating Systems type
  • os.uptime() : Shows pc runtime after last reboot
  • os.hostname() : Shows the computer name
  • os.release() : Shows OS version
  • os.homedir() : Shows home directory path
  • os.freemem () : Shows available RAM
  • os.totalmem() : Show entire memory capacity

2. Path

It helps manipulating folder & file path

  • Path module is very useful because every Operating system has different path delimiter
  • Windows type & POSIX type
  • Window type : separated by ₩ (i.e., C:₩Users₩cplou)
  • POSIX type is used in Unix based Operating system such as macOS and Linux
  • POSIX type : separated by (i.e., /home/cplou)
const path = require('path');

const string = __filename;

// path.sep: /
console.log('path.sep:', path.sep); 
// path.delimiter: :
console.log('path.delimiter:', path.delimiter); 
console.log('------');
// path.dirname(): /Users/gp/Desktop/node_module
console.log('path.dirname():', path.dirname(string));
// path.extname(): .js
console.log('path.extname():', path.extname(string));
// path.basename(): path.js
console.log('path.basename():', path.basename(string));
// path.basename(): path
console.log('path.basename():', path.basename(string, path.extname(string)));
console.log('------');
// path.parse() { root: '/',
//   dir: '/Users/gp/Desktop/node_module',
//   base: 'path.js',
//   ext: '.js',
//   name: 'path' }
console.log('path.parse()', path.parse(string));
// path.format(): C:\users\cplou/pathjs
console.log('path.format():', path.format({
    dir: 'C:\\users\\cplou',
    name: 'path',
    ext: 'js',
}));
// path.normalize(): C:/users\\cplou\path.js
console.log('path.normalize():', path.normalize('C://users\\\\cplou\\\path.js'));
console.log('------');
// path.isAbsolute(): false
console.log('path.isAbsolute():', path.isAbsolute('C:\\'));
// path.isAbsolute(): false
console.log('path.isAbsolute():', path.isAbsolute('./home'));
console.log('------');
// path.relative(): ../C:\
console.log('path.relative():', path.relative('C:\\users\\cplou\\path.js', 'C:\\'));
// path.join(): /Users/gp/Desktop/users/cplou
console.log('path.join():', path.join(__dirname, '..', '..', '/users', '.', '/', 'cplou'));
// path.resolve(): /cplou
console.log('path.resolve():', path.resolve(__dirname, '..', 'users', '.', '/cplou'));
  • __filename__dirname represents current file and current folder path respectively
  • path:sep : path delimiter (i.e., Windows : \ , POSIX : / )
  • path.delimiter : env variable delimiter (i.e., Windows : ; , POSIX :)
  • path.dirname(path) : file Path
  • path.extname(path) : file extension
  • path.basename(path, extension) : file name
  • path.parse(path) : separate the file path into root, dir, base, ext, name
  • path.format(object) : path.parse() object to file path
  • path.noramlize(path) : remove duplicates / \
  • path.isAbsolute(path) : return boolean tells whether the file path is absolute path or relative path
  • path.join(path, …) : combine into a path
  • path.resolve(path, …) : combine into a path
difference between path.join & path.resolve
--
- path.resolve : absolute path
- path.join : relative path
path.join('/a', '/b', 'c'); // /a/b/c
path.resolve('/a', '/b', 'c'); // /b/c

3. Url

It helps manipulate Internet address (url)

  • They are two types of url manipulation 1) WHATWG url 2) traditional node url
const url = require('url');

const URL = url.URL;
const myURL = new URL('https://christosploutarchou.com/posts/nodejs/#authentication-vs-authorization');
console.log('new URL():', myURL);
// new URL(): URL {
//     href:
//      'https://christosploutarchou.com/posts/nodejs/#authentication-vs-authorization',
//     origin: 'https://christosploutarchou.com',
//     protocol: 'https:',
//     username: '',
//     password: '',
//     host: 'christosploutarchou.com,
//     hostname: 'https://christosploutarchou.com',
//     port: '',
//     pathname: '/posts/nodejs/',
//     search: '',
//     searchParams: URLSearchParams {},
//     hash: '#authentication-vs-authorization' }

console.log('url.format():', url.format(myURL));
// url.format(): https://christosploutarchou.com/posts/nodejs/#authentication-vs-authorization
console.log('--------');
const parsedUrl = url.parse('https://christosploutarchou.com/posts/nodejs/#authentication-vs-authorization');
console.log('url.parse():', parsedUrl);
// url.parse(): Url {
//     protocol: 'https:',
//     slashes: true,
//     auth: null,
//     host: 'christosploutarchou.com',
//     port: null,
//     hostname: https://christosploutarchou.com',
//     hash: '#authentication-vs-authorization',
//     search: null,
//     query: null,
//     pathname: '/posts/nodejs//',
//     path: '/posts/nodejs/',
//     href:
//      'https://christosploutarchou.com/posts/nodejs/#authentication-vs-authorization'}
console.log('url.format():', url.format(parsedUrl));
// url.format():https://christosploutarchou.com/posts/nodejs/#authentication-vs-authorization
  • url.parse(address) : separate url
  • url.format(object) : reassemble url

4. querystring

Convert searchParams of url into an object

const url = require('url');
const querystring = require('querystring');

const parsedUrl = url.parse('http://www.google.com/?page=3&limit=10&category=nodejs&category=javascript');
const query = querystring.parse(parsedUrl.query);
console.log('querystring.parse():', query);
// querystring.parse(): [Object: null prototype] { page: '3', limit: '10', category:
// [ 'nodejs', 'javascript' ] }
console.log('querystring.stringify():', querystring.stringify(query));
// querystring.stringify(): page=3&limit=10&category=nodejs&category=javascript