Javascript Notes part-1 (NodeJS,Node-fetch,Axios)

Useful :

1] JS engines - https://youtu.be/BMKWdLX9w3M 

2] Check if node and npm are installed in terminal :

  • node -v
  • npm -v

3] If you run the below command in the folder which has the package.json file,then npm will read the package.json file and install all the packages at once.

npm install

4] Open Vscode in current directory

code .

---------------------------------------------------------------------------------------------------------------


JavaScript was initially created to “make web pages alive”.The programs in this language are called scripts.They can be written right in a web page’s HTML and run automatically as the page loads.Javascript is a interpreted language ,JavaScript is not a class-based object-oriented language instead it is a Proto-type based language.

History of Javascript  (Useful : 1] Click)

In 1989 the world wide web (WWW) was invented with the purpose to improve information sharing between universities and science institutes. One year later the first web-browser emerged simply named: ‘WorldWideWeb’. However, the first commercial-like browser was introduced a few years later — in 1993 — by the Netscape Communications Corporation. In the beginning of 1995 Netscape was one of the most popular web-browsers out there.

Web pages before the existence of JavaScript were very static. Lists, dates, and links were all hard-coded into your HTML, and any sort of dynamic functionality was encoded in the head of the HTML document as a header.  To expand and further develop the WWW Netscape Communications Corporation created JavaScript (at that time called "Mocha"). The goal of JS was to enable the creation of dynamic websites and making the web more dynamic with interactions. In the later versions when it was commercially shipped with Netscape Navigator browser, it was renamed to "Livescript" and then eventually "Javascript".


The first Javascript Engine/Interpreter was created by Netscape. Before Netscape went out of business they submitted to ECMA International Organisation the creation of a Javascript Standard or Specification. The standardization of JS would provide a pre-defined specification that one needs to follow when creating any Javascript based Interpreters.

The standard for Javascript that was created, is now called the "ECMAscript". The term "Javascript" does'nt represent a single open source language but rather various implementation of ECMAscript,which we also call as "JS Engines"

ECMAScript provides the rules, details, and guidelines that a scripting language must observe to be considered ECMAScript compliant. The ECMAscript basically standardizes the features that these various Implementations need to follow.

JavaScript engines are commonly found in web browsers, including V8 in Chrome, SpiderMonkey in Firefox, and Chakra in Edge. Each engine is like a language module for its application, allowing it to support a certain subset of the JavaScript language.

Since its inception in 1995, the language that has ultimately come to be known as JavaScript has gone through several iterations and versions. More updates and language features are also added to the ECMAscript every few years. In such cases these various Implementations of JS are also updated by their vendors to keep upto-date with the ECMAscript, providing developers more JS features.

NOTE : The ES6 version i.e sixth edition of ECMAscript provided major changes and modern features to the specification. It basically added features like promises,destructuring,Let,Const etc to the Javascript Language.

NOTE : In 2015 Ecma International decided to switch to annual releases of ECMAScript providing updates every year. Accordingly, Ecma International also started to name new editions of the ECMAScript specification based on the year they are released. In short, ES6 and ES2015 are two different names for the same thing.

ECMAScript is a specification for what a scripting language could look like. Releasing a new edition of ECMAScript does not mean that all JavaScript engines in existence suddenly have those new features. It is up to the groups or organizations who are responsible for JavaScript engines to be up-to-date about the latest ECMAScript specification, and to adopt its changes.

Therefore, developers tend to ask questions like, “What version of ECMAScript does this browser support?” or “Which ECMAScript features does this browser support?” They want to know if Google, Mozilla, and Microsoft have gotten around to updating their browsers’ JavaScript engines — for example V8, SpiderMonkey, and Chakra, respectively — with the features described in the latest ECMAScript.

NOTE : This blog here explains which features were added to in various ECMAscript versions.

NOTE : Today Javascript is so popular that every year new updates are added to the ECMAscript specification. Due to this we often need to use transcompilers like "Babel" to support/run new ES features in older browsers which have'nt upgraded to latest ECMAscript version.


Chicken or the egg ?

A confusing bit of history is that JavaScript was created in 1996. It was then submitted to Ecma International in 1997 for standardization, which resulted in ECMAScript. At the same time, because JavaScript conformed to the ECMAScript specification, JavaScript is an example of an ECMAScript implementation. That leaves us with this fun fact: ECMAScript is based on JavaScript, and JavaScript is based on ECMAScript.

--------------------------------------------------------------------------------------------------------------

Useful : 1] Click here

Javascript Engines

There are 2 ways you can run javascript :

1] Inside HTML of a Web-page using <script> tag on a web browser

2] Using Js as a stand-alone language without HTML or a web browser 

In both cases we use a Javascript Engine which is a computer program that executes JavaScript code.JavaScript engines are typically developed by web browser vendors, and every major browser has one.

But the use of Js engines is not limited to wen browsers,we can use these engines on our pc to run javascript as a standalone language (just like python or java).

The first JavaScript engines were mere interpreters, but all relevant modern engines use just-in-time compilation for improved performance.The first JavaScript engine was created by Brendan Eich in 1995 for the Netscape Navigator web browser. It was a rudimentary interpreter for the nascent language Eich invented. (This evolved into the SpiderMonkey engine, still used by the Firefox browser.)

The first modern JavaScript engine was V8, created by Google for its Chrome browser. V8 debuted as part of Chrome in 2008, and its performance was much better than any prior engine.The key innovation was just-in-time compilation, which can significantly improve execution times.


Node.JS

https://www.freecodecamp.org/news/what-exactly-is-node-js-ae36e97449f5/

Node.js is an open-source, cross-platform, back-end JavaScript runtime environment that runs on the V8 engine and executes JavaScript code outside a web browser. 

It is one of the most popular javascript engines built on top of chrome's v8 engine.

It also comes with "npm" or "node package manager" which is a default package manager that comes with node js.It is kind of similar to pip in python.

Nodejs also enables developers to use Js for backend rather than other backend languages like php.

(Running JS in visual studio code using NodeJS - Click here)

-------------------------------------------------------------------------------------------------------------

Javascript Syntax

JavaScript ignores spaces, tabs, and newlines that appear in JavaScript programs. You can use spaces, tabs, and newlines freely in your program.

Semicolons are Optional

Simple statements in JavaScript are generally followed by a semicolon character, just as they are in C, C++, and Java. JavaScript, however, allows you to omit this semicolon if each of your statements are placed on a separate line. For example, the following code could be written without semicolons.

<script language = "javascript" type = "text/javascript">
   <!--
      var1 = 10
      var2 = 20
   //-->
</script>

But when formatted in a single line as follows, you must use semicolons −

<script language = "javascript" type = "text/javascript">
   <!--
      var1 = 10; var2 = 20;
   //-->
</script>

Note − It is a good programming practice to use semicolons.

Case Sensitivity

JavaScript is a case-sensitive language. This means that the language keywords, variables, function names, and any other identifiers must always be typed with a consistent capitalization of letters.


-------------------------------------------------------------------------------------------------------------

console.log()

 It is used to log information into the console.It is mostly used during testing purposes.

console.log("Hello world !");

-------------------------------------------------------------------------------------------------------------

Variables

Use the "var" keyword to declare or initialise a variable.JavaScript is untyped language. This means that a JavaScript variable can hold a value of any data type. Unlike many other languages, you don't have to tell JavaScript during variable declaration what type of value the variable will hold.

var age = 10
console.log("I am "+age+" years old !")

Variables can be declared and initialize without the var keyword. However, a value must be assigned to a variable declared without the var keyword.

The variables declared without the var keyword becomes global variables, irrespective of where they are declared.

It is Not Recommended to declare a variable without var keyword because it can accidentally overwrite an existing global variable.


-------------------------------------------------------------------------------------------------------------

Before ES6 (2015), JavaScript had only Global Scope and Function Scope.

ES6 introduced two important new JavaScript keywords: let and const.

These two keywords provide Block Scope in JavaScript.

Variables declared inside a { } block cannot be accessed from outside the block:

-------------------------------------------------------------------------------------------------------------

Let in javascript

The let keyword was introduced in ES6 (2015).

Cannot be Redeclared

Variables defined with let cannot be redeclared. Variables defined with var can be.

You cannot accidentally redeclare a variable.

With let you can not do this:

Example

let x = "John Doe";

var x = 0;

// SyntaxError: 'x' has already been declared

Block Scope

Variables declared inside a { } block cannot be accessed from outside the block:

Example

{
  let x = 2;
}
// x can NOT be used here

Variables declared with the var keyword can NOT have block scope.


-------------------------------------------------------------------------------------------------------------

const in javascript

Variables defined with const cannot be Redeclared.

Variables defined with const cannot be Reassigned.

Variables defined with const have Block Scope.

It is used to declare constant variables

const PI = 3.14159265359;

// You can create a constant array:
const cars = ["Saab""Volvo""BMW"];


-------------------------------------------------------------------------------------------------------------

If...else




if(10>0){

    console.log("10 is greater than 0 !")

}else{

    console.log("10 is not greater than 0 !")

}






if(10>0){

    console.log("10 is greater than 0 !")

}else if(10<0){

    console.log("10 is less than 0 !")

}else{

    console("10 is the same as 0 !")

}




-------------------------------------------------------------------------------------------------------------

switch statement




var num1 = 100;
var num2 = 200;

switch(num2-num1){

case 100:
    console.log("Answer is 100 !")
    break;
case 0:
    console.log("Answer is 0 !")
    break;
case 10:
    console.log("Answer is 10 !")

}



-------------------------------------------------------------------------------------------------------------

While loop & For loop




var i = 10;

while(i>0){
    console.log(i);
    // decrement by 1
    i--;
}





var i = 0;

for(i;i<10;i++){

    console.log(i)

}



-------------------------------------------------------------------------------------------------------------

Functions in Javascript

The most common way to define a function in JavaScript is by using the function keyword, followed by a unique function name, a list of parameters (that might be empty), and a statement block surrounded by curly braces.



function add_numbers(number1,number2){
    return number1+number2;
}

var result = add_numbers(100,200);

console.log(result)



Arrow Functions

Arrow functions were introduced in ES6.Arrow functions allow us to write shorter function syntax:



var names = (num1,num2=> {return num1+num2;}

var result = names(100,200);
console.log(result)



Note: This works only if the function has only one statement.


-------------------------------------------------------------------------------------------------------------

Arrays


The Array object lets you store multiple values in a single variable. It stores a fixed-size sequential collection of elements of the same type.


var names = ["A","B","C","D"]

console.log(names[1])

// inserts an element
names.push("E")

console.log(names)



Array Functions


1] The JavaScript method toString() converts an array to a string of (comma separated) array values.


var fruits = ["Banana", "Orange", "Apple", "Mango"];

fruits = fruits.toString()
console.log(fruits)



2] The pop() method removes the last element from an array


var fruits = ["Banana", "Orange", "Apple", "Mango"];

fruits.pop()
console.log(fruits)



3] Shifting is equivalent to popping, working on the first element instead of the last.The shift() method removes the first array element and "shifts" all other elements to a lower index.


var fruits = ["Banana", "Orange", "Apple", "Mango"];

fruits.shift()
console.log(fruits)



4] The concat() method creates a new array by merging (concatenating) existing arrays.


const myGirls = ["Cecilie", "Lone"];
const myBoys = ["Emil", "Tobias", "Linus"];

const myChildren = myGirls.concat(myBoys);
console.log(myChildren)



5] The forEach() method calls a function (a callback function) once for each array element.

Syntax

// Arrow function
forEach((element) => { ... } )
forEach((element, index) => { ... } )
forEach((element, index, array) => { ... } )

// Callback function
forEach(callbackFn)
forEach(callbackFn, thisArg)

// Inline callback function
forEach(function(element) { ... })
forEach(function(element, index) { ... })
forEach(function(element, index, array){ ... })
forEach(function(element, index, array) { ... }, thisArg)

// ARROW FUNCTION

var student_rolls = [10,20,30,40,50,60];


student_rolls.forEach( (value,index,array)=> {
    array[index] = value*100;
})


console.log(student_rolls)
// [ 1000, 2000, 3000, 4000, 5000, 6000 ]


//------------------------------------------------------


// REGULAR FUNCTION

var student_rolls = [10,20,30,40,50,60];


function addHundred(value,index,array){
    array[index] = value+100;
}

student_rolls.forEach(addHundred)


console.log(student_rolls)
// [ 110, 120, 130, 140, 150, 160 ]



6] The map() method creates a new array by performing a function on each array element. The map() method does not change the original array.



var student_rolls = [10,20,30,40,50,60];

// callback function
function addHundred(value,index,array){
    return value+100;
}


var student_rolls2 = student_rolls.map(addHundred)
console.log(student_rolls2)
// [ 110, 120, 130, 140, 150, 160 ]


7] The filter() method creates a new array with array elements that passes a test. The filter() method takes each element in an array and it applies a conditional statement against it. If this conditional returns true, the element gets pushed to the output array. If the condition returns false, the element does not get pushed to the output array.

The syntax for filter is similar to map, except the callback function should return true to keep the element, or false otherwise.


var student_rolls = [1,2,3,6,7,9,13,17,16,20];

// function returns true if value is even
function even_filter(value,index,array){
    return value%2==0;
}


var student_rolls2 = student_rolls.filter(even_filter)
console.log(student_rolls2)
// [ 2, 6, 16, 20 ]



8] The reduce() method executes a reducer/ function for each value of an array & returns a single value which is the function's accumulated result,but it does not change the original array.

array.reduce(function(total, currentValue), initialValue)
function()Required.
A function to be run for each element in the array.
totalRequired.
The initialValue, or the previously returned value of the function.
currentValueRequired.
The value of the current element.

const numbers = [15,3,1,4];

function getSum(total,num) {
  return total + num*2;
}

const result = numbers.reduce(getSum,0);
console.log(result)  // 46

9] The indexOf() method searches an array for an element value and returns its position.


var student_rolls = [1,2,3,6,7,9,13,17,16,20];

// index of 16
const i = student_rolls.indexOf(16)

console.log(i)  // 8



-------------------------------------------------------------------------------------------------------------

Try...Catch

try {
         // Code to run
         [break;]
      } 
      
      catch ( e ) {
         // Code to run if an exception occurs
         [break;]
      }


-------------------------------------------------------------------------------------------------------------

"this" keyword in javascript

The JavaScript this keyword refers to the object it belongs to.


-------------------------------------------------------------------------------------------------------------

(Useful : Click here)

OBJECTS in Javascript

JavaScript variables can contain one or many values.Objects are variables too. But objects can contain many values.Object values are written as name : value pairs (name and value separated by a colon).

Actually there is no ‘dictionary’ type in JavaScript but we can create key-value pairs by using JavaScript Objects.



const person = {

    // define properties
    name:"Deepesh",
    surname:"Mhatre",
    age:19,
    skills:["Programming","Machine Learning"],

    // define method
    introduce_yourself:function(){
        console.log("Hello,I am Deepesh !");
    }

}

// acess values
console.log(person.age)
console.log(person.skills)
person.introduce_yourself();



It is a common practice to declare objects with the const keyword.

A JavaScript object is a collection of named values.JavaScript objects are containers for named values, called properties and methods.

Objects written as name value pairs are similar to:

  • Dictionaries in Python
  • Hash maps in Java


Object Constructors

Sometimes we need a "blueprint" for creating many objects of the same "type".The way to create an "object type", is to use an object constructor function.



function Person(firstlastageeye) {
    this.firstName = first;
    this.lastName = last;
    this.age = age;
    this.eyeColor = eye;
  }


// create new objects
const myFather = new Person("John""Doe"50"blue");
const myMother = new Person("Sally""Rally"48"green");


In the example above, function Person() is an object constructor function.Objects of the same type are created by calling the constructor function with the new keyword.

JavaScript has built-in constructors for native objects:

new String()    // A new String object
new Number()    // A new Number object
new Boolean()   // A new Boolean object
new Object()    // A new Object object
new Array()     // A new Array object
new RegExp()    // A new RegExp object
new Function()  // A new Function object
new Date()      // A new Date object


Javascript Prototypes

All JavaScript objects inherit properties and methods from a prototype. If you want to add a new property or method to an existing object constructor you cannot add it dynamically,you'll have to add it to the constructor function itself.

Example

function Person(first, last, age, eyecolor) {
  this.firstName = first;
  this.lastName = last;
  this.age = age;
  this.eyeColor = eyecolor;
  this.nationality = "Indian"; // new property
}

The JavaScript prototype property allows you to add new properties to object constructors:



function Person(firstlastageeye) {
    this.firstName = first;
    this.lastName = last;
    this.age = age;
    this.eyeColor = eye;
  }

// adding a new property to existing constructor
Person.prototype.nationality="Indian"

const person1 = new Person("Deepesh","Mhatre",19,"Black");
console.log(person1.nationality);




-------------------------------------------------------------------------------------------------------------

OBJECT ORIENTED PROGRAMMING


(Useful : Click here)

CLASSES (Pre-ES6)

Before ES6 we used the object constructors to create classes in javascript.

Example 1]


// constructor function
var Person = function(name,surname,age){

    this.name=name;
    this.surname=surname;
    this.age=age;

    this.eat_food=function() {console.log("Eating Food !");};
}

const p1 = new Person("Deep","Mhatre",19);
p1.eat_food();


Example 2]



// constructor function
function Person (name,surname,age){

    this.name=name;
    this.surname=surname;
    this.age=age;

    this.eat_food=function() {console.log("Eating Food !");};
}

const p1 = new Person("Deep","Mhatre",19);
p1.eat_food();



INHERITANCE (Pre-ES6)

https://www.tutorialsteacher.com/javascript/inheritance-in-javascript



CLASSES using "class" keyword (POST-ES6)


ECMAScript 2015, also known as ES6 introduced JavaScript Classes.JavaScript Classes are templates for JavaScript Objects.

Use the keyword class to create a class. Always add a method named constructor()

class Car {
  constructor(name, year) {
    this.name = name;
    this.year = year;
  }
}

The constructor method is a special method:

  • It has to have the exact name "constructor"
  • It is executed automatically when a new object is created
  • It is used to initialize object properties
If you do not define a constructor method, JavaScript will add an empty constructor method.

Syntax

class ClassName {
  constructor() { ... }
  method_1() { ... }
  method_2() { ... }
  method_3() { ... }
}



class Person{

    constructor(name,surname){

        // define attributes
        this.name=name;
        this.surname=surname;
        this.age;
    }

    // define a method
    introduce_yourself(){
        console.log("Hello,My name is "+this.name+" "
        +this.surname+" and I am "+this.age+" years old !")
    }

}

// create a object
let person1 = new Person("Deepesh","Mhatre")
person1.age = 19;
person1.introduce_yourself()





-------------------------------------------------------------------------------------------------------------


INHERITANCE

To create a class inheritance, use the extends keyword.




class Person{

    constructor(name,surname){

        // define attributes
        this.name=name;
        this.surname=surname;
        this.age;
    }

    // define a method
    introduce_yourself(){
        console.log("Hello,My name is "+this.name+" "
        +this.surname+" and I am "+this.age+" years old !")
    }

}

// inherit the person class
class New_Person extends Person{


}


// create object of new class
let person1 = new New_Person("Deepesh","Mhatre")
person1.age = 10
person1.introduce_yourself()



-------------------------------------------------------------------------------------------------------------

GETTERS & SETTERS

It can be smart to use getters and setters for your properties, especially if you want to do something special with the value before returning them, or before you set them.

To add getters and setters in the class, use the get and set keywords.

Example

Create a getter and a setter for the "carname" property:

class Car {
  constructor(brand) {
    this.carname = brand;
  }
  get cnam() {
    return this.carname;
  }
  set cnam(x) {
    this.carname = x;
  }
}

let myCar = new Car("Ford");

document.getElementById("demo").innerHTML = myCar.cnam;
Note: even if the getter is a method, you do not use parentheses when you want to get the property value.

The name of the getter/setter method cannot be the same as the name of the property, in this case carname.

Many programmers use an underscore character _ before the property name to separate the getter/setter from the actual property:


-------------------------------------------------------------------------------------------------------------

STATIC METHODS

Static class methods are defined on the class itself.You cannot call a static method on an object, only on an object class.



class Animal{

    static bark(){
        console.log("Bhau Bhau !!")
    }

}

// calling a static method
Animal.bark()




-------------------------------------------------------------------------------------------------------------


MAP data structure in Javascript

A Map object holds key-value pairs where the keys can be any datatype.A Map object remembers the original insertion order of the keys.

Actually there is no ‘dictionary’ type in JavaScript but we can create key-value pairs by using JavaScript Objects.

Essensial Methods

MethodDescription
new Map()Creates a new Map object
set()Sets a value for a key in a Map object
get()Gets a value for a key in a Map object
entries()Returns an array of the key/value pairs in a Map object
keys()Returns an array of the keys in a Map object
values()Returns an array of the values in a Map object




let myNumbers = new Map();

// insert values
myNumbers.set(0,"Zero");
myNumbers.set(1,"One");
myNumbers.set(2,"Two");
myNumbers.set(3,"Three");

// get values
let i = myNumbers.get(3);
console.log(i)

// delete values
myNumbers.delete(0);

// display entire map
console.log(myNumbers);



NOTE : Being able to use an Object as a key is an important Map feature. Useful : Click here


-------------------------------------------------------------------------------------------------------------

SET data structure in Javascript


A Set is a collection of unique values.Each value may occur only once in a Set.A Set can hold any values of any data type.

Set Object Methods and Properties

new Set()Creates a new Set object
add()Adds a new element to the Set
clear()Removes all elements from a Set
delete()Removes an element specified by its value.
entries()Returns an array of the values in a Set object
has()Returns true if a value exists
forEach()Invokes a callback for each element
keys()Returns an array of the values in a Set object
values()Same as keys()
sizeReturns the element count




let myNumbers = new Set();

// insert values
myNumbers.add(0);
myNumbers.add(0);
myNumbers.add(1);
myNumbers.add(2);

// display entire set
console.log(myNumbers); //{ 0, 1, 2 }


-------------------------------------------------------------------------------------------------------------


Singly Linkedlist in Javascript


class Node {
    constructor(data) {
        this.data = data;
        this.next = null;
    }

}

class Linkedlist {
    constructor() {
        this.head = null;
    }

    add(data) {
        var new_node = new Node(data);
        if (this.head == null) {
            this.head = new_node;
        } else {
            var temp = this.head;
            while (temp.next != null) {
                temp = temp.next;
            };
            temp.next = new_node;
        };
    };

    remove() {
        if (this.head == null) {
            console.log("Linkedlist is empty !");

        } else {
            var temp = this.head;
            while (temp.next.next != null) {
                temp = temp.next;
            }
            temp.next = null;
            console.log("Value removed !")
        };
    };

    display_all() {
        if (this.head == null) {
            console.log("Linkedlist is empty !");
        } else {

            var temp = this.head;
            while (temp!= null) {
                console.log(temp.data);
                temp=temp.next;
            };
        };

    };

};


let linky = new Linkedlist();
linky.add(10);
linky.add(11);
linky.add(12);
linky.add(13);
linky.add(14);
linky.remove();
linky.remove();

linky.display_all();




-------------------------------------------------------------------------------------------------------------


Javascript Modules 

A module in JavaScript is just a file containing related code. Modules are small units of independent, reusable code that is desired to be used as the building blocks in creating a non-trivial Javascript application. 

Unlike other programming languages where we can directly import the functions from other files,in Javascript we need to first export the required things before we import them into other files.

In Javascript, we have 2 main conventions to create and import modules :

  • CommonJS Modules
  • ES Modules


CommonJs Modules

The CommonJS is one of the many conventions to create modules in javascript. It has not been accepted as a standard way of creating modules in javascript, but many JS engines like NodeJS support it.

In CommonJs format we export things using the "moduls.exports" and then import then into another file using the "require()" function.

One of the main features of using CommonJs modules is that we can call "require()" from anywhere inside conditions and functions, because 'require' is a function i.e plain javascript.

Example] Below we demonstrate to create CommonJS modules.

1] Exporting a single function


# MyFirst.js

function add2numbers(num1,num2){
    return num1+num2;
}

// exporting single function
module.exports = add2numbers;



// importing single function
const add2numbers = require("./MyFirst")


result = add2numbers(2,3)
console.log("RESULT : ",result)


2] Exporting a multiple functions


# MyFirst.js

function add2numbers(num1,num2){
    return num1+num2;
}

function multiply2numbers(num1,num2){
    return num1*num2;
}

// exporting multiple functions
module.exports = {add2numbers,multiply2numbers};



// importing entire module
const math = require("./MyFirst")


result = math.add2numbers(2,3)
console.log("ADD RESULT : ",result)

result = math.multiply2numbers(2,3)
console.log("MUL RESULT : ",result)


Or we can also do this to avoid writing the module name everytime we need to use a function. 


// importing entire module
const {add2numbers,multiply2numbers} = require("./MyFirst")


result = add2numbers(2,3)
console.log("ADD RESULT : ",result)

result = multiply2numbers(2,3)
console.log("MUL RESULT : ",result)


3] We can use either module.exports or exports.FunctionName


# MyFirst.js

exports.add2numbers=(num1,num2)=>{
    return num1+num2;
}

exports.multiply2numbers=(num1,num2)=>{
    return num1*num2;
}


// importing entire module
const math = require("./MyFirst")


result = math.add2numbers(2,3)
console.log("ADD RESULT : ",result)

result = math.multiply2numbers(2,3)
console.log("MUL RESULT : ",result)

4] Calling 'require' from inside a condition or function


# MyFirst.js

exports.add2numbers=(num1,num2)=>{
    return num1+num2;
}

exports.multiply2numbers=(num1,num2)=>{
    return num1*num2;
}


if(10>5){

// importing entire module
const math = require("./MyFirst")


result = math.add2numbers(2,3)
console.log("ADD RESULT : ",result)

result = math.multiply2numbers(2,3)
console.log("MUL RESULT : ",result)

}


ES Modules

In ES2015 of the ECMAscript a new standard for creating and importing modules in javascript was introduced. The features like "import" and "export" keywords were introduced. The ES module format is the official standard format to package JavaScript code for reuse and most modern web browsers natively support the modules.

The 'export' keyword is used to export things like objects, functions, variables from the module, whereas the 'import' keywod is used to import those things into another files.

There are 2 types of exports : 

  • Named exports - These help us export multiple things at once. We can export things with a specific name, but we need to then import them using the same name.
  • Default exports - We are able to export only a single function, objects, or primitive values but we can use the different name to import them.During the import, we are able to ommit the curly bares and use any name.

Example] Below we demonstrate to create ES modules using both named and default exports.

1] Create some named exports.


// exporting everyting at ones
export { Sum, object, array, string, number, boolean, Null };

// Import everything at ones
import * as myfunctions from './Test.js'

//--------------------------------------------------

// exporting with different names
export { Sum as adding, number as binary }

// Import with they names
import {adding,number} from './Test.js'

2] Create some default exports.


// index.js
function func() {
    return "this a default export."
 }
 export default func;

//-------------------------------------------------

 // test.js
 import myDefaultExport from "./index.js";
 console.log(myDefaultExport()); // this a default export.



ES Modules in NodeJs (Useful : 1] Click)

The ES module format is the official standard format to package JavaScript code for reuse and most modern web browsers natively support the modules. Node.js, however only supports the CommonJS module format by default, since most of the codebase of NodeJs is written using the commonJs modules.

The ES module format was introduced in Node.js v8.5.0 as the JavaScript module system was standardized. However, starting with version 13.2.0, Node.js has stable support of ES modules. 

If you try to create ES modules in Nodejs you may get errors as its treats all modules as CommonJs modules. Below are some of the ways we can enable the use of ES Modules in NodeJs :

1] We can also simply enable ES modules in a Node.js package by changing the file extensions from .js to .mjs.

NOTE : The file which is importing and also the file exporting the programs must have ".mjs" extensions.


// util.mjs

export function add(a, b) {
    return a + b;
}

export function subtract(a, b) {
    return a - b;
}

//-----------------------------------

// app.mjs

import {add, subtract} from './util.mjs'

console.log(add(5, 5)) // 10
console.log(subtract(10, 5)) // 5


2] Another way to enable ES modules in your project can be done by adding a "type: module" field inside the Package.Json file. If it does'nt exist then create one using 'npm init' command.


// Package.Json

{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "type": "module"  // new
}


3] Alternatively, you can install and set up a transpiler like Babel to compile your ES module syntax down to CommonJS syntax. Projects like React and Vue support ES modules because they use Babel under the hood to compile the code.

-------------------------------------------------------------------------------------------------------------

Useful : 1] Click here


NPM (node package manager)


NPM is a package manager for Node.js packages, or modules if you like. 

www.npmjs.com hosts thousands of free packages to download and use.The NPM program is installed on your computer when you install Node.js


Installing External Packages


To install a public package, on the command line, run

npm install <package_name>

OR

npm install <package_name>@<version> (Install specific pakage version)


There are 2 ways to install packages in node :

  • Global Install
  • Local Install


Generally we would install packages locally into the project directory,this ensures that when we deploy our project it includes all the necessary modues. Also installing packages locally means they will only be acessable from that folder.

Most packages are installed locally but some projects need to be installed gobally,which means that the package will be acessable from any directory.

To download and install packages globally, on the command line, run the following command :

npm install -g <package_name>


Package.json


The package.json file is the heart of Node.js system. It is the manifest file of any Node.js project and contains the metadata of the project. It also keeps track of what all packages are installed in the project.

This file is super useful,especially if other people want to clone your project and install all the packages you used. Using package.json, you can install all those packages at once.

If you run the below command in the folder which has the package.json file,then npm will read the package.json file and install all the packages at once.

npm install

(This also comes handy during deployment since the the server can install all packages directly by looking at package.json file)

If there is a package.json file in the directory in which npm install is run, npm installs the latest version of the package that satisfies the semantic versioning rule declared in package.json.If there is no package.json file, the latest version of the package is installed.


Creating "package.json" file


package.json file can be created in two ways :


1] Using npm init : Running this command, system expects user to fill the vital information required as discussed above. It provides users with default values which are editable by the user.

npm init

or

npm init -y (Automatically create boilerplate file)

2] Writing directly to file : One can directly write into file with all the required information and can include it in the Node project.

Example: A demo package.json file with the required information.

{
  "name": "GeeksForGeeks",
  "version": "1.0.0",
  "description": "GeeksForGeeks",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node start.js",
  },
  "engines": {
    "node": ">=7.6.0",
    "npm": ">=4.1.2"
  },
  "author": "GeeksForGeeks",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.17.1",
    "express": "^4.15.2",
    "express-validator": "^3.1.2",
    "mongoose": "^4.8.7",
    "nodemon": "^1.14.12",
  },
  "devDependencies": {},
  "repository": {
    "type": "git",
    "url": "https://github.com/gfg/gfg.git" //sample git repo url
  },
  "bugs": {
    "url": "https://github.com/gfg/gfg/issues"
  },
  "homepage": "https://github.com/gfg/gfg#readme"
}

Explanation of Package.json  :


(See this link to learn about package.json in detail : Click)

  • name: The name of the application/project.
  • version: The version of application. The version should follow semantic versioning rules.
  • description: The description about the application, purpose of the application, technology used like React, MongoDB, etc.
  • main: This is the entry/starting point of the app. It specifies the main file of the application that triggers when the application starts. Application can be started using npm start.
  • scripts: The scripts which needs to be included in the application to run properly. You can run thee scripts using "npm run <script-name>"
  • engines: The versions of the node and npm used. These versions are specified in case the application is deployed on cloud like heroku or google-cloud.
  • keywords: It specifies the array of strings that characterizes the application.
  • author: It consist of the information about the author like name, email and other author related information.
  • license: The license to which the application confirms are mentioned in this key-value pair.
  • dependencies: The third party package or modules installed using npm are specified in this segment.
  • devDependencies: The dependencies that are used only in the development part of the application are specified in this segment. These dependencies do not get rolled out when the application is in production stage.
  • repository: It contain the information about the type and url of the repository where the code of the application lives is mentioned here in this segment.
  • bugs: The url and email where the bugs in the application should be reported are mentioned in this segment.

Here, “body-parser”“express”“express validator”“mongoose” and “nodemon” are the modules/packages installed using npm



------------------------------------------------------------------------------------------------------------


Nodes-Modules Directory


Whenever you install a package using "npm install",a new directory named "node_modules" is created in your project directory. This folder is where npm stores all the packages installed.

When you npm install them, they are downloaded from the web and copied into the node_modules folder and nodejs is trained to look for them there when you import them.

To confirm that npm install worked correctly, in your module directory, check that a node_modules directory exists and that it contains a directory for the package(s) you installed,to list all installed packages run the command from project folder:

npm list


NOTE : Just like PyPi in python,we also have a npm repository for dependencies , you can check it out here : https://www.npmjs.com/package/repository


NOTE : When uploading project to github,you must include a ".gitignore" file,this file includes names of files to ignore during github upload. You must always gitignore the node_modules folder before uploading to github.



Updating Installed Packages (useful - link)


Below command will update all the packages in package.json

npm update

Npm packages follow "semantic versioning",which is a system of software versioning. Each version is a 3 digit number where 1st digit is called "Major",2nd digit is caled "Minor" and the final digit is called "Patch".


Major version updates occur when the changes to the module/software are big and not backwards compatible,which also means that updating our npm package will most likely break our code which depends on the old version.

Minor and Patch updates include small fixes and new features which likely will not break our code since these version are safe to update.

NOTE : When you first install a package ,npm will install the latest version of that package,overtime we may need to update these packages for bug fixes and new features. However we need to make sure that we do not accidently update to a new major version which may break our code. Fortunately npm have some safety features by default toavoid this.

In our package.json file npm will display all installed packages with their specific version numbers. If you look closely you'll see a carrot (^) symbol, npm uses this symbol as an indicator to limit which versions it'll update the packages .

{
  "dependencies": {
    // notice the carrot (^) symbol
    "tensorflow": "^2.7.1"
  }
}

The carrot symbol indicates that npm will update the packages to the latest 'minor' and 'patch' versions for the currently installed 'major' version. 


Package-lock.json  :

When you install a package using npm, it will also generate another file called "package-lock.json". This file records the actual specific version of package and dependency that you have installed locally.

package-lock. json is automatically generated for any operations where npm modifies either the node_modules tree, or package. json . It describes the exact tree that was generated, such that subsequent installs are able to generate identical trees, regardless of intermediate dependency updates.

The goal of package-lock. json file is to keep track of the exact version of every package that is installed so that a product is 100% reproducible in the same way even if packages are updated by their maintainers.

The main reason this file exist is to solve compatibility issues which can arise when using a package.json file from a different environment (like github repository).

NOTE : So in simple words if you have a package.json and package-lack.json file,then npm will install the exact 'major','minor','patch' versions of that packages recorded in package-lock.json file.


-------------------------------------------------------------------------------------------------------------


Asynchronous Javascript

JavaScript is a single-threaded programming language which means only one thing can happen at a time. That is, the JavaScript engine can only process one statement at a time in a single thread,this also means you can’t perform long operations such as network access without blocking the main thread which can make the web page unresponsive.

That’s where asynchronous JavaScript comes into play. Using asynchronous JavaScript (such as callbacks, promises, and async/await), you can perform long network requests without blocking the main thread.


CallBack Functions

A callback function is a function which is passed as an argument to another function. Callbacks make sure that a function is not going to run before a task is completed but will run right after the task has completed. It helps us develop asynchronous JavaScript code.

There is a built-in method in JavaScript called “setTimeout()”, which calls a function or evaluates an expression after a given period of time 


function printName(){
    console.log("Hello !")
}

// executes the function after 3 secs
setTimeout(printName,3000)



When using the JavaScript function setInterval(), you can specify a callback function to be executed for each interval:


function printName(){
    console.log("Hello !")
}

// executes the function every 2 secs
setInterval(printName,2000)



Callback Hell

Callback Hell, also known as Pyramid of Doom, is an anti-pattern seen in code of asynchronous programming. It is a slang term used to describe and unwieldy number of nested “if” statements or functions.

If you are not expecting your application logic to get too complex, a few callbacks seem harmless. But once your project requirements start to swell, you will quickly find yourself piling layers of nested callbacks.


Before promises were inroduced to javascript, it was very common to get into the callback-hell. This usually happens when you want to execute a series of functions which depend on the output of their previous function.

NOTE : The easiest way to avoid callback hell is to use javascript promises or async/await functions.


Promises

Promises are one of the ways to deal with asynchronous operations in javascript. The main difference between Callback Functions and Promises is that we attach a callback to a Promise rather than passing it. So we still use callback functions with Promises, but in a different way called "chaining".

A promise has 2 possible outcomes: it will either be kept when the time comes, or it won’t.This is also the same for promises in JavaScript. When we define a promise in JavaScript, it will be resolved when the time comes, or it will get rejected.

NOTE : Most of the times you'll be consuming promises , rather than creating promises.

A Promise is an object. There are 3 states of the Promise object :

  • Pending: Initial State, before the Promise succeeds or fails
  • Resolved: Completed Promise
  • Rejected: Failed Promise


Creating Promise Step by Step :


1] Firstly, we use a constructor to create a Promise object,It takes two parameters, one for success (resolve) and one for fail (reject). Here 'reject' and 'resolve' are both functions. Resolve() changes the state of promise from pending to fullfilled and Reject() changes the state of promise from pending to rejected.

Finally, there will be a condition. If the condition is met, the Promise will be resolved, otherwise it will be rejected. We call resolve/reject as per our conditions.




const myPromise = new Promise((resolve, reject) => {  

    if(10>5) {    
        resolve('Promise is resolved successfully.');  
    } else {    
        reject('Promise is rejected');  
    }

});


function promise_pending(){console.log("Promise in pending state !")}

myPromise.then((value) => { console.log(value) })
    .catch((value)=>{ console.log(value) })
    .finally(promise_pending)


// Promise is resolved successfully.
// Promise in pending state !



The then( ) method is called if the Promise is resolved. Then we can decide what to do with the resolved Promise.What if the Promise fails? Then, we need to use the catch( ) method. The finally() method is called regardless the prpmise is completed or not,it takes a callback function which is executed.

NOTE : When you resolve a promise using the resolve(), then the callback function passed to then() is moved to the Microtask Queue of Event loop where it waits for its execution.

You can also pass callback functions to reject/resolve functions to be called after the promise is fullfilled or rejected.


const myPromise = new Promise((resolve, reject) => {  

    if(10>15) {    
        resolve('Promise is resolved successfully.');  
    } else {    
        reject('Promise is rejected');  
    }

});

function promise_fullfilled(){console.log("Promise in Fullfilled state !")}
function promise_rejected(){console.log("Promise in Rejected state !")}


myPromise.then(promise_fullfilled).catch(promise_rejected)



Promise Chaining (useful : 1] Click)

Promise chaining is a syntax that allows you to chain together multiple asynchronous tasks in a specific order. This is great for complex code where one asynchronous task needs to be performed after the completion of a different asynchronous task.The idea is that the result is passed through the chain of .then handlers.




const myPromise = new Promise((resolve, reject) => {
  if (10 > 5) {
    resolve(0);
  } else {
    reject(-1);
  }
});

function promiseRejected() {
  console.log("Promise in Rejected state !");
}

myPromise
  .then((value) => {
    console.log("Adding 10 ...");
    return value + 10;
  })
  .then((value) => {
    console.log("Adding 20 ...");
    return value + 20;
  })
  .then((value) => {
    console.log("Multiplying by 10 ...");
    return value * 10;
  })
  .then((value) => {
    console.log("Final Value is ", value);
  })
  .catch(promiseRejected);  // Catch is triggered only if promise is rejected

// Adding 10 ...
// Adding 20 ...
// Multiplying by 10 ...
// Final Value is  300 <--- NOTICE THIS



The whole thing works, because every call to a .then returns a new promise, so that we can call the next .then on it.When a handler returns a value, it becomes the result of that promise, so the next .then is called with it.

A classic newbie error: technically we can also add many .then to a single promise. This is not chaining.


const myPromise = new Promise((resolve, reject) => {
  if (10 > 5) {
    resolve(0);
  } else {
    reject(-1);
  }
});

function promiseRejected() {
  console.log("Promise in Rejected state !");
}

myPromise.then((value) => {
  console.log("Adding 10 ...");
  return value + 10;
});

myPromise.then((value) => {
  console.log("Adding 20 ...");
  return value + 20;
});

myPromise.then((value) => {
  console.log("Multiplying by 10 ...");
  return value * 10;
});

myPromise.then((value) => {
  console.log("Final Value is ", value);
});


// Adding 10 ...
// Adding 20 ...
// Multiplying by 10 ...
// Final Value is  0 <--- NOTICE THIS


What we did here is just several handlers to one promise. They don’t pass the result to each other; instead they process it independently.


All 
.then on the same promise get the same result – the result of that promise. So in the code above all alert show the same: 1

You can also directly resolve a promise, thereby pushing the given callback function into the Microtask Queue, which wil be executed at the end when all the synchronous code has been executed. This is also one way we can perform long running tasks by simply pushing them through the event loop.


function billion5(){
    let i=0
    while(i<2000000000){
        i++;
    }
    console.group("5 Billion completed !")
}

console.log("Started...")
let result = Promise.resolve().then((value)=>{billion5()})
console.log("Ending...")

// Started...
// Ended...
// 5 Billion completed !


Async & Await

The async/await were added to the Javascript language right after the introduction of promises. This is supposed to be the better way to write promises and it helps us keep our code simple and clean.

The async/await feature just provides a syntactic sugar to make the code for promises more readable. It makes your asynchronous code look like synchronous code but in reality it'll do same thing as promises.

The "async" keyword before a function means that the function will always return a promised automatically. If we dont explicitly return a promise, then the returned values are automatically wrapped around a resolved promise. If the returned promise is resolved then .then() is called, else the .catch() is executed.


function getName(rollNumber){
    students = {11:"Rohan",21:"Deepesh",13:"Kiran"}
    return Promise.resolve(students[rollNumber])
}

//--------------------------------------
// The below function is same as above. If you dont explicitly return
// a promise then it'll take the return value and automatically resolves
// it as a promise.

async function getName(rollNumber){
    students = {11:"Rohan",21:"Deepesh",13:"Kiran"}
    return students[rollNumber]
}

NOTE : We dont need to use the resolve() or reject() inside an async function. The promise is considered resolved if we return a value, else its unresolved if we return an error. 


async function mathFunc(num1,num2){
    if(num1>num2) { return num1-num2}
    return num1+num2;
}

mathFunc(3,4)
.then((value)=>{
    console.log("OUTPUT : "+ value)  // OUTPUT : 7
    return value;
})
.then((value)=>{
    console.log("Multiplied by 10 : "+ value*10) // Multiplied by 10 : 70
})

//----------------Same as Above-----------------------------------------------

async function mathFunc(num1,num2){
    // explicitly return a promise
    if(num1>num2) { return Promise.resolve(num1-num2)}
    return Promise.resolve(num1+num2);
 }
 
 mathFunc(3,4)
 .then((value)=>{
     console.log("OUTPUT : "+ value)  // OUTPUT : 7
     return value;
 })
 .then((value)=>{
     console.log("Multiplied by 10 : "+ value*10) // Multiplied by 10 : 70
 })

The returned value is passed to the ".then()" method,you can acess it just like in promises, while the errors are passed to ".catch()" method.


async function mathFunc(num1,num2){
    if(num1>num2) { return num1-num2}
    else{  throw "A Test Error !"}
 }
 
 mathFunc(3,4)
 .then((value)=>{
     console.log("OUTPUT : "+ value)
     return value;
 })
 .catch((error)=>{
     console.log("Error Occured : "+error)
     // OUTPUT : TypeError: A Test Error !
 })
 

NOTE : Throwing errors manually is not a good practice, so we must always wrap the function code inside try/catch blocks.


const verifyUser = async function (username, password) {
    try {
      // do something here
    } catch (e) {
      //handle errors as needed
    }
  };
 
  function promise_fullfilled(){console.log("Promise in Fullfilled state !")}
  function promise_rejected(){console.log("Promise in Rejected state !")}
 
 
  test_function().then(promise_fullfilled).catch(promise_rejected)


Await keyword

The "await" keyword is used inside the async function. The await keyword is used to wait for a promise to be resolved. When Js encounters an await keyword it literally pauses the execution at that point and resumes execution only when the promise is fullfilled i.e resolved or rejected.

NOTE : The "await" keyword can only be used inside the async function.

Basically we can create promises and wait for them to complete execution without disturbing the main thread or making web page unresponsive. In the below example you can see how the execution stops and then continues again when the promise is fullfilled.


async function someTask(){

    // create new promise
    let mypromise = new Promise((resolve,reject)=>{
        // long running task
        let i = 0
        while(i<100){i++;}
        resolve("Some Value")
    })

    console.log("Started...")
    let output = await mypromise;
    console.log("OUTPUT : ",output)
    console.log("Ending...")
}


someTask()

// Started...
// OUTPUT :  Some Value
// Ending...


Example] Below is an example of how we can run a blocking code using await and promises.


// Wrap the long task in a promise
function doLongTask() {
  return new Promise((resolve, reject) => {
    console.log("Long Task started...");

    // some blocking code
    let i = 0;
    while (i < 2000000000) {
      i++;
    }

    console.log("Long Task ended...");
    resolve("Some Value");
  });
}


// Now use it freely inside async function
async function getThingsDone() {
  console.log("async function started...");
  let output = await doLongTask();
  console.log("OUTPUT : ", output);
  console.log("async function ended...");
  return output;
}


getThingsDone().then((value) => {
  console.log("Final : " + value);
}).catch((err)=>{
    console.log("Error : ",err)
})

// async function started...
// Long Task started...
// Long Task ended...
// OUTPUT :  Some Value
// async function ended...
// Final : Some Value


-------------------------------------------------------------------------------------------------------------

Useful : 1] Click


Destructuring assignment

The destructuring assignment syntax is a JavaScript expression that makes it possible to unpack values from arrays, or properties from objects, into distinct variables.

It allows us to extract data from arrays, objects, and maps and set them into new, distinct variables. Destructuring allows us to extract multiple properties, or items, from an array​ at a time.


Object Destructuring


Before ES6:

// assigning object attributes to variables
const person = {
    name: 'Sara',
    age: 25,
    gender: 'female'    
}

let name = person.name;
let age = person.age;
let gender = person.gender;

console.log(name); // Sara
console.log(age); // 25
console.log(gender); // female

From ES6:

// assigning object attributes to variables
const person = {
    name: 'Sara',
    age: 25,
    gender: 'female'    
}

// destructuring assignment
let { name, age, gender } = person;

console.log(name); // Sara
console.log(age); // 25
console.log(gender); // female

Note: When destructuring objects, you should use the same name for the variable as the corresponding object key.

Note: The order of the name does not matter in object destructuring.


If you want to assign different variable names for the object key, you can use:

const person = {
    name: 'Sara',
    age: 25,
    gender: 'female'    
}

// destructuring assignment
// using different variable names
let { name: name1, age: age1, gender:gender1 } = person;

console.log(name1); // Sara
console.log(age1); // 25
console.log(gender1); // female


Array Destructuring

You can also perform array destructuring in a similar way. For example,

const arrValue = ['one', 'two', 'three'];

// destructuring assignment in arrays
const [x, y, z] = arrValue;

console.log(x); // one
console.log(y); // two
console.log(z); // three


-------------------------------------------------------------------------------------------------------------


Javascript Json

`

The JSON format is syntactically similar to the code for creating JavaScript objects. Because of this, a JavaScript program can easily convert JSON data into JS objects.Since the format is text only, JSON data can easily be sent between computers, and used by any programming language.

  • JSON.parse()  It is a built-in function which converts JSON strings into JS objects.
  • JSON.stringify() : It is a built in function for converting an object into a JSON string.


var json = '{"name":"John", "age":30, "city":"New York"}'

// converts json to object
var obj = JSON.parse(json)

// printing values
console.log(obj["name"])
console.log(obj["age"])
console.log(obj["city"])

// output :
// John
// 30
// New York



When using the JSON.parse() on a JSON derived from an array, the method will return a JavaScript array, instead of a JavaScript object.


var myarr = '["Ford", "BMW", "Audi", "Fiat"]';

// converts json to object
var myarr = JSON.parse(myarr)

// printing values
console.log(myarr)

// output :
// [ 'Ford', 'BMW', 'Audi', 'Fiat' ]



NOTE :  A common use of JSON is to exchange data to/from a web server. When sending data to a web server, the data has to be a string.Convert a JavaScript object into a string with JSON.stringify().



const obj = {name: "John", age: 30, city: "New York"};

// convert to json string
const myJSON = JSON.stringify(obj);

console.log(myJSON)

// outputs :
// {"name":"John","age":30,"city":"New York"}




const arr = ["John", "Peter", "Sally", "Jane"];
const myJSON = JSON.stringify(arr);

console.log(myJSON)

// NOTE : myJSON is now a string, and ready to be sent to a server

// outputs :
// ["John","Peter","Sally","Jane"]



-------------------------------------------------------------------------------------------------------------

CORS POLICY ERROR

NOTE : When sending API requests from the browser, you'll likely get a "CORS" error. To solve the CORS error,you'll have to add some code on your backend to enable CORS.

The code is different for each technology , eg - The code to enable cors is different for Flask and FastAPI.

Check this link to get the code for different backend technologies for enabling CORS : https://enable-cors.org/server.html

For FASTAPI check this : https://fastapi.tiangolo.com/tutorial/cors/

-------------------------------------------------------------------------------------------------------------

Useful : 1] Click


GET/POST Request with Javascript Fetch()


The fetch() method in JavaScript is used to request to the server and load the information in the webpages. The request can be of any APIs that returns the data of the format JSON or XML.

fetch() is a mechanism that lets you make simple AJAX (Asynchronous JavaScript and XML) calls with JavaScript.

Asynchronous means that you can use fetch to make a call to an external API without halting the execution of other instructions. That way, other functions on the site will continue to run even when an API call has not been resolved.

NOTE fetch() is not part of the JavaScript spec, but the WWTAG. As a result, you will not be able to use it in a Node.js environment (unless you install a special module).You can use the async import() function from CommonJS to load node-fetch asynchronously.

npm install node-fetch
const fetch = (...args) => import('node-fetch').then(({default: fetch}) => fetch(...args));


NOTE : fetch() method returns a promise, so you need to nest a .then() method to handle the resolution


GET Request


This method accept two parameters as mentioned above and described below:

  • URL: It is the URL to which the request is to be made.
  • Options: It is an array of properties. It is an optional parameter.

It returns a promises whether it is resolved or not. The return data can be of the format JSON or XML.It can be the array of objects or simply a single object.

The data returned from the API is not usually in a useable form. So you'll need to convert the data to a form which your JavaScript can operate with. Thankfully, you can use the json() method to do just that.


// importing fetch()
const fetch = (...args) => import('node-fetch')
              .then(({default: fetch}) => fetch(...args));

// gets a user's data
let api_url = "https://jsonplaceholder.typicode.com/posts/1"

// send POST request
fetch(api_url)
.then(response =>{
    // converting response to json
    return response.json()
})
.then(response=>{
    console.log(response)
})

/*

OUTPUT :

{
  userId: 1,
  id: 1,
  title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit',
  body: 'quia et suscipit\n' +
    'suscipit recusandae consequuntur expedita et cum\n' +
    'reprehenderit molestiae ut ut quas totam\n' +
    'nostrum rerum est autem sunt rem eveniet architecto'
}

*/



NOTE : fetch() method will always suceed no matter what response,so we have to manually check if our response is sucessful or not.


// importing fetch()
const fetch = (...args) =>
  import("node-fetch").then(({ default: fetch }) => fetch(...args));

// gets a user's data
let api_url = "https://jsonplaceholder.typicode.com/posts/1";

// send POST request
fetch(api_url)
  .then((response) => {
    // check if response is sucessful
    if (response.ok) {
      console.log("Response is sucessful !");
      // converting response to json
      return response.json();
    } else {
      console.log("Response NOT sucessful !");
    }
  })
  .then((response) => {
    console.log(response);
  });



POST Request


For a post request, you'll need to pass an object of configuration options as a second argument. The optional object can take a lot of different parameters. In this case, include only the most necessary information.

Because you're sending a POST request, you'll need to declare that you're using the POST method.

You'll also need to pass some data to actually create the new blog post. Since you're sending JSON data, you'll need to set a header of Content-Type set to application/json. Finally, you'll need the body, which will be a single string of JSON data.


// importing fetch()
const fetch = (...args) =>
  import("node-fetch").then(({ default: fetch }) => fetch(...args));


// create's new user in database
let api_url = " http://dummy.restapiexample.com/api/v1/create";


// converting data to json string so we send in post request
var data = JSON.stringify({name:"Aman",salary:"50000",age:"25"})


// creating options
const options = {
    method: 'POST',
    headers: {
    'Content-Type': 'application/json',
    },
    body: data,
    };


// send POST request
fetch(api_url,options)
  .then((response) => {
    // check if response is sucessful
    if (response.ok) {
      console.log("Response is sucessful !");
      // converting response to json
      return response.json();
    } else {
      console.log("Response NOT sucessful !");
    }
  })
  .then((response) => {
    console.log(response);
  });

/*
OUTPUT :
Response is sucessful !
{
  status: 'success',
  data: { name: 'Aman', salary: '50000', age: '25', id: 5768 },
  message: 'Successfully! Record has been added.'
}
*/



-------------------------------------------------------------------------------------------------------------

Useful : 1] Click


AXIOS

Axios is a Promise-based HTTP client for JavaScript which can be used in your front-end application and in your Node. js backend. By using Axios it's easy to send asynchronous HTTP request to REST endpoints and perform CRUD operations.

Fetch() uses a two-step process when dealing with JSON data; after making an initial request you’ll then need to call the .json() method on the response in order to receive the actual data object. Also fetch() method does'nt have proper error handling features,Axios improves upon this things.

These are basic methods for generating requests in axios :

  1. axios.request(config)
  2. axios.get(url[, config])
  3. axios.delete(url[, config])
  4. axios.head(url[, config])
  5. axios.options(url[, config])
  6. axios.post(url[, data[, config]])
  7. axios.put(url[, data[, config]])
  8. axios.patch(url[, data[, config]])

Axios Response object

When we send a request to a server, it returns a response. The Axios response object consists of the following attributes :

  • data - the payload returned from the server
  • status - the HTTP code returned from the server
  • statusText - the HTTP status message returned by the server
  • headers - headers sent by server
  • config - the original request configuration
  • request - the request object


GET Request



const axios = require('axios');

let api_url = "https://jsonplaceholder.typicode.com/posts/1"


// Make a GET request
axios.get(api_url)
  .then( response => {
    // handle success
    console.log("Request is Sucessful !")
    console.log(response.data);
  })
  .catch(error => {
    // handle error
    console.log("Request is NOT Sucessful !")
    console.log(error);
  })
 


/*

OUTPUT :
Request is Sucessful !
{
  userId: 1,
  id: 1,
  title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit',
  body: 'quia et suscipit\n' +
    'suscipit recusandae consequuntur expedita et cum\n' +
    'reprehenderit molestiae ut ut quas totam\n' +
    'nostrum rerum est autem sunt rem eveniet architecto'
}

*/


We can also write the above code using async/await keyword like this...


// importing axios
const axios = require("axios");

async function getUser() {
  const api_url = "https://jsonplaceholder.typicode.com/posts/1";
  try {
    const response = await axios.get(api_url);
    var data = response.data;
    console.log("Request is Successful !");
    console.log(data);
    return data;
  } catch (error) {
    console.log("Request is NOT Successful !");
    console.error(error);
  }
}

const api_response = getUser();

console.log(api_response);

/*

OUTPUT :
Promise { <pending> }
Request is Successful !
{
  userId: 1,
  id: 1,
  title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit',
  body: 'quia et suscipit\n' +
    'suscipit recusandae consequuntur expedita et cum\n' +
    'reprehenderit molestiae ut ut quas totam\n' +
    'nostrum rerum est autem sunt rem eveniet architecto'
}
*/



POST Request


Unlike fetch() method where we had to manually create the 'options' and also convert data to json string,here axios automatically does that for us.



// importing axios
const axios = require("axios");

// create's new user in database
let api_url = "https://reqres.in/api/users";

// No need to convert to json string
var data = {name: "morpheus",job: "salesman"}

axios
  .post(api_url, data)
  .then((response) => {
    // handle success
    console.log("Request is Sucessful !");
    console.log(response.data);
  })
  .catch((error) => {
    // handle error
    console.log("Request is NOT Sucessful !");
    console.log(error);
  });

/*

OUTPUT :
Request is Sucessful !
{
  name: 'morpheus',
  job: 'salesman',
  id: '389',
  createdAt: '2021-11-26T14:37:42.508Z'
}
*/



Or we can also create asyc function like this...


// importing axios
const axios = require("axios");


async function sendPOSTrequest(data) {
   const api_url = "https://reqres.in/api/users";
  try {
    const response = await axios.post(api_url,data);
    const response_data = response.data;
    console.log("Request is Successful !");
    console.log(response_data)
    return response_data;
  } catch (error) {
    console.log("Request is NOT Successful !");
    console.error(error);
  }
}


// Sending post request
var data = {name: "morpheus",job: "salesman"}
var api_response = sendPOSTrequest()


/*

OUTPUT :
Request is Sucessful !
{ id: '577', createdAt: '2021-11-26T14:53:27.179Z' }
*/


---------------------------------------------------------------------------------------------------------------

Optional Chaining Operator

Optional chaining is a feature in JavaScript that allows you to safely access nested properties of an object without worrying about whether any of those properties are null or undefined. It uses the question mark (?.) operator to check if a property exists before attempting to access it's nested properties.

Without optional chaining, if we try to access a nested property of an object that is 'null' or 'undefined', we would get a runtime 'TypeError' and the program would stop executing. This can be especially problematic when dealing with deeply nested objects or objects that may have optional properties. Without optional chaining, we would need to manually use a lot of "if" statements to check for the existence of nested properties in an object.

By using optional chaining, we can safely access nested properties without worrying about whether they are 'null' or 'undefined'. If a property does not exist, the expression simply returns undefined and the program continues executing.


// main.js

const person = {
    name: "Deepesh",
    surname: "Mhatre",
    age: 19,
    skills: ["Programming", "Machine Learning"],
    introduce_yourself: function () { console.log("Hello,I am Deepesh !") }
}

console.log(person.name)  // Deepesh

// Check if the nested property exists before trying to access it
if (person.name && person.name.someNonExistingProperty &&
    person.name.someNonExistingProperty.getSomething) {
    console.log(person.name.someNonExistingProperty.getSomething);
} else {
    console.log(undefined);
}

// Check if each level of the nested properties exist before trying to access them
if (person.age && person.age.something1 && person.age.something1.something2 &&
    person.age.something1.something2.something3) {
    console.log(person.age.something1.something2.something3);
} else {
    console.log(undefined);
}

//----------------------------- WITH OPTIONAL CHAINING--------------------------------

const person = {
    name: "Deepesh",
    surname: "Mhatre",
    age: 19,
    skills: ["Programming", "Machine Learning"],
    introduce_yourself: function () { console.log("Hello,I am Deepesh !") }
}

console.log(person.name)  // Deepesh

// ERROR : Cannot read properties of undefined (reading 'getSomething')
console.log(person.name.someNonExistingProperty.getSomething)
console.log(person.name.someNonExistingProperty?.getSomething) // undefined

// Error: Cannot read properties of undefined (reading 'something2')
console.log(person.age.something1.something2.something3)
console.log(person.age.something1?.something2?.something3) // undefined


NOTE : If a property or method accessed using optional chaining is null or undefined, the expression will short circuit and return undefined without evaluating the rest of the expression.


Nullish Coalescing Operator

The Nullish Coalescing operator (??) is a new operator introduced in ECMAScript 2020, used to provide a fallback value for variables that may be null or undefined. If the value is either 'null' or 'undefined', the operator returns the fallback value. If the value is not 'null' or 'undefined' the operator returns the actual value.


// main.js

let fetchedData;

if (fetchedData !== null && fetchedData !== undefined) {
    fetchedData = "Deepesh";
} else {
    fetchedData = "Value is Null !";
}

console.log(fetchedData); // "Deepesh"
fetchedData = null;

let result;
if (fetchedData !== null && fetchedData !== undefined) {
    result = fetchedData;
} else {
    result = "Fetched Value is Null !";
}

console.log(result); // "Fetched Value is Null !"

//------------------------------WITH NULLISH OPERATOR---------------------------------

let fetchedData = "Deepesh" ?? "Value is Null !";
console.log(name); // "Deepesh"

fetchedData = null;
const result = fetchedData ?? "Fetched Value is Null !";
console.log(result); // "Fetched Value is Null !"

NOTE : The Nullish Coalescing operator ?? is particularly useful when working with data fetched from an API because the API may not always return the data we expect. In cases where the data is missing or nullish, we can use the Nullish Coalescing operator to provide a default value.

---------------------------------------------------------------------------------------------------------------









Comments