Event Bubbling in Javascript

With bubbling, the event is first captured and handled by the innermost element and then propagated to outer elements. With capturing, the process is in reverse. We usually attach an event to a handler using the addEventListener function.

addEventListener("click", handler, useCapture=false)

The third argument useCapture is the key. The default value is false. So, it will be a bubbling model where the event is handled by the innermost element first and it propagates outwards till it reaches the parent element. If that argument is true, it is capturing model.

<div onClick="divHandler()">
    <ul onClick="ulHandler">
        <li id="foo"></li>
    </ul>
</div>
<script>
function handler() {
 // do something here
}
function divHandler(){}
function ulHandler(){}
document.getElementById("foo").addEventListener("click", handler)
</script>

When we click the list element, the order of execution of handlers is like this in bubbling (default) model.

handler() => ulHandler() => divHandler()

Hoisting in Javascript

Hoisting is a process of pushing the declared variables to the top of the program while running it. For Ex:

doSomething(foo); // used before
var foo; // declared later

 In this mechanism, a JavaScript VM does two things while running a program:

  1. First scan the program, collect all the variable and function declarations and assign memory spaces for it.
  2. Run the program now by filling variable values assigned any, if not, fill undefined

In the above code snippet, console.log prints “undefined”. It is because in the first pass variable foo is collected. VM looks for any value defined for variable foo. This hoisting can result in many JavaScript code situations where code can throw errors in some places and uses undefined silently in another. You should be knowing hoisting to clear the ambiguity! See a few examples!

HTML Response Status Codes

  1. Information Response – starts with 100
  2. Successful Response – starts with 200 (200 success ok)
  3. Redirection Messages – starts with 300
  4. Client Error Response – starts with 400 (404 Not found is important)
  5. Server Error Response – starts with 500

Data Types in Javascript

8 Data types in total. Main Primitive and Object. There are 7 primitive data types and Object. Together they are 8.

Below is the list:

  1. Boolean – Boolean is a logical data type that can have only the values true or false.
  2. Null –  A null value represents a reference that points, generally intentionally, to a nonexistent or invalid object or address. The meaning of a null reference varies among language implementations.
  3. Undefined – undefined is a primitive value automatically assigned to variables that have just been declared, or to formal arguments for which there are no actual arguments.
  4. Number – JS Number is a numeric data type. Integers, Floats, Doubles, or Bignums — all fall under Number
  5. BigInt – In JavaScriptBigInt is a numeric data type that can represent integers in the arbitrary precision format. In other programming languages different numeric types can exist, for examples: Integers, Floats, Doubles, or Bignums.
  6. String – In any computer programming language, a string is a sequence of characters used to represent text.
  7. Symbol – A value having the data type Symbol can be referred to as a “Symbol value”.  In a JavaScript run-time environment, a symbol value is created by invoking the function Symbol which dynamically produces an anonymous, unique value. A symbol may be used as an object property.

Symbol can have an optional description, but for debugging purposes only.

Symbol value represents a unique identifier. For example,

// here are two symbols with the same description,
let Sym1 = Symbol("Sym");
let Sym2 = Symbol("Sym");
  
console.log(Sym1 == Sym2); // returns "false"
// Symbols are guaranteed to be unique.
// Even if we create many symbols with the same description,
// they are different values.
let Sym = Symbol("Sym");

alert(Sym); // TypeError: Cannot convert a Symbol value to a string

let Sym = Symbol("Sym");

alert(Sym.toString()); // Symbol(Sym), now it works

Reference : Mozilla

Angular Quick Reference

What is Ahead of Time (AOT)?

The Angular Ahead-of-Time (AOT) compiler converts your Angular HTML and TypeScript code into efficient JavaScript code during the build phase before the browser downloads and runs that code. Compiling your application during the build process provides a faster rendering in the browser.

Angular offers two ways to compile your application:

  1. Just-in-Time (JIT), which compiles your app in the browser at runtime.
  2. Ahead-of-Time (AOT), which compiles your app at build time.

JIT compilation is the default when you run the ng build (build only) or ng serve (build and serve locally) CLI commands:

ng build
ng serve

For AOT compilation, include the --aot option with the ng build or ng serve command:
content_copy

ng build --aot
ng serve --aot

Why compile with AOT?

  1. Faster rendering: With AOT, the browser downloads a pre-compiled version of the application. The browser loads executable code so it can render the application immediately, without waiting to compile the app first.
  2. Fewer asynchronous requests: The compiler inlines external HTML templates and CSS style sheets within the application JavaScript, eliminating separate ajax requests for those source files.
  3. Smaller Angular framework download size: There’s no need to download the Angular compiler if the app is already compiled. The compiler is roughly half of Angular itself, so omitting it dramatically reduces the application payload.
  4. Detect template errors earlier: The AOT compiler detects and reports template binding errors during the build step before users can see them.
  5. Better security: AOT compiles HTML templates and components into JavaScript files long before they are served to the client. With no templates to read and no risky client-side HTML or JavaScript evaluation, there are fewer opportunities for injection attacks.

Reference Link : Click Here

Regular Expressions – Regex

This post explains the basics of Regex. As a javascript developer, it’s very important to know how to perform basic Regex and Solve problems. It’s a universal concept. This post focuses on Regex with javascript.

Below are the different ways to create a Regex expression with javascript.

var re = /ar/;
var re = new RegExp('ar'); 

We can match strings using exec function after defining regex.

re.exec('car'); // returns ["ar", index: 1, input: "car"]
re.exec('cab'); // returns null

There are few special character classes which allow us to write complex regular expressions.

There are many types of elements in RegEx. Some of them are:

  • Characters Ex: \w — Alphanumeric, \d — Decimal, \D — Non decimal
  • Character classes Ex: [x-y] in range x to y, [^x] not x
  • Quantifiers Ex: +, ?, * (greedy and lazy matchers)
  • Boundaries Ex: ^(beginning of input), $(end of input)
/* Character class */
var re1 = /[AEIOU]/;
re1.exec("Oval"); // returns ["O", index: 0, input: "Oval"]
re1.exec("2456"); // null
var re2 = /[1-9]/;
re2.exec('mp4'); // returns ["4", index: 2, input: "mp4"]

/* Characters */
var re4 = /\d\D\w/;
re4.exec('1232W2sdf'); // returns ["2W2", index: 3, input: "1232W2sdf"]
re4.exec('W3q'); // returns null

/* Boundaries */
var re5 = /^\d\D\w/;
re5.exec('2W34'); // returns ["2W3", index: 0, input: "2W34"]
re5.exec('W34567'); // returns null
var re6 = /^[0-9]{5}-[0-9]{5}-[0-9]{5}$/;
re6.exec('23451-45242-99078'); // returns ["23451-45242-99078", index: 0, input: "23451-45242-99078"]
re6.exec('23451-abcd-efgh-ijkl'); // returns null

/* Quantifiers */
var re7 = /\d+\D+$/;
re7.exec('2abcd'); // returns ["2abcd", index: 0, input: "2abcd"]
re7.exec('23'); // returns null
re7.exec('2abcd3'); // returns null
var re8 = /<([\w]+).*>(.*?)<\/\1>/;
re8.exec('<p>Hello JS developer</p>'); //returns  ["<p>Hello JS developer</p>", "p", "Hello JS developer", index: 0, input: "<p>Hello JS developer</p>"]

Along with exec, there are other functions namely matchsearch and, replace are available for finding a string in another using regular expressions. But these functions should be used on the string itself.

"2345-678r9".match(/[a-z A-Z]/); // returns ["r", index: 8, input: "2345-678r9"]
"2345-678r9".replace(/[a-z A-Z]/, ""); // returns 2345-6789

Link to learn more: Click Here

HTTP Request

Promises and async/await:

const fetchData = () => {
    fetch('https://api-github.com') //to get data
    .then(resp => {            //.then method to return json object
         resp.json().then(data => { //to parse raw data on resp object
         console.log(data);
         });
     });
}

Modern way:

const fetchData = async () => {
     const resp = await fetch('https://api-github.com');
     const data = await resp.json();
     console.log(data);
};
fetchData();
var xhr = new XMLHttpRequest();    
xhr.open("GET", "https://reqres.in/api/unknown", true);   
xhr.onload = function () {   
console.log(xhr.responseText, xhr.responseType);    
};    
xhr.send();

Address Book – Javascript

Address Book

HTML:

<!doctype html>
<html lang="en">

<head>
	<meta charset="UTF-8">
	<title>AddressBook</title>
	<link rel="stylesheet" href="addressbook.css">
	<script src="addressbook.js"></script>
</head>

<body>
	<div class="container">
		<div class="addForm panel">
			<h1>Address Book</h1>
			<label for="fullname" class="labelForm">Name</label>
			<input type="text" id="fullname" class="formFields" placeholder="Enter your name">
			<label for="phone" class="labelForm">Phone Number</label>
			<input type="text" id="phone" class="formFields" placeholder="Phone">
			<label for="email" class="labelForm">Email</label>
			<input type="text" id="email" class="formFields" placeholder="Email Here">
			<br>
			<br>
			<button id="add" class="button-blue">Add Contact</button>
		</div>
		<div class="contactList">
			<h1>Contact List</h1>
			<div class="addbook">
				<div class="entry">
					<div class="name"><p></p></div>
					<div class="email"><p></p></div>
					<div class="phone"><p></p></div>
					<div class="del"><a href="#">Delete</a></div>
				</div>
			</div>
		</div>
	</div>
</body>

</html>

CSS

.panel {
    background: #8dcb66;
    padding: 1em;
    width: 92.5%;
    margin: auto;
    max-width: 30em;
    color: white;
}

input {
    width: 100%;
    box-sizing: border-box;
    font-size: 1em;
    margin: 0.5em;
    padding: 0.5em;
}

label {
    width: 100%;
    font-size: 1em;
    padding: 10px;
}

button {
    text-align: center;
    border-radius: 3px;
    cursor: pointer;
    display: inline-block;
    font-family: Verdana, sans-serif;
    font-size: 12px;
    font-weight: 400;
    line-height: 20px;
    padding: 9px 16px 9px;
    margin: 16px 0 0 16px;
    transition: all 20ms ease-out;
    vertical-align: top;
}

.addbook {
    margin: 20px;
}

.contactList {
    background: #7f74ba;
    color: white;
    margin: 2px;
    padding: 5px;
    text-align: center;
}

.entry {
    border-radius: 3px;
    height: 40px;
    border-bottom: 1px solid;
    border-top: 1px solid;
    color: white;
    padding: 10px;
}

.entry .name {
    width: 300px;
    float: left;
    padding: 11px;
}

.entry .email {
    width: 300px;
    float: left;
    padding: 11px;
}

.entry .phone {
    width: 300px;
    float: left;
    padding: 11px;
    padding-right: 30px;
}

.entry .del {
    width: 40px;
    float: right;
    padding: 9px;
    margin-right: 30px;
}

.entry p {
    margin: 0px;
    font-family: Verdana, sans-serif;
    font-size: 12px;
}

.entry .del a {
    border-radius: 10px;
    cursor: pointer;
    font-family: Verdana, sans-serif;
    color: #FFF;
    font-size: 12px;
    padding: 8px;
    background: rgb(255, 100, 100);
    text-decoration: none;
}

.button-blue {
    background-color: #42b0e3;
    background-image: linear-gradient(to bottom, #42b0e3, #2ba9e3);
    border: 1px solid #107db0;
    box-shadow: inset 0 1px 0 #7cd4fc, inset 0 -1px 0 #2696c9, inset 0 0 0 1px #59b7e3, 0 2px 4px rgba(0, 0, 0, 0.2);
    color: white;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}

.h2 {
    font-family: Verdana, sans-serif;
    color: white;
}

JavaScript

window.onload = function () {
    //buttons
    var addBtn = document.getElementById("add");
    var addFormDiv = document.querySelector(".addForm");

    //form fields:
    var fullname = document.getElementById("fullname");
    var phone = document.getElementById("phone");
    var email = document.getElementById("email");

    //address book display
    var addBookdiv = document.querySelector(".addbook");

    //Intialize storage array
    var dataArray = [];

    //eventListeners
    addBtn.addEventListener("click", addToBook);
    addBookdiv.addEventListener("click", removeContact);

    function structure(fullname, phone, email) {
        this.fullname = fullname;
        this.phone = phone;
        this.email = email;
    }

    function addToBook() {
        //test if fields are empty
        var testIfempty = fullname.value != '' && phone.value != '' && email.value != '';
        //console.log(testIfempty);

        if (testIfempty) {
            //add contents to array and add contents to localstorage
            var obj = new structure(fullname.value, phone.value, email.value);
            dataArray.push(obj);
            localStorage['contactInfo'] = JSON.stringify(dataArray);

            //clear form
            clearForm();

            //update display from the form data collected
            displayContactInfo();
        }

    }

    function clearForm() {
        var filledForm = document.querySelectorAll(".formFields");
        for (var i in filledForm) {
            filledForm[i].value = "";
        }
    }

    function removeContact(e) {
        if (e.target.classList.contains("removeButton")) {
            var rmId = e.target.getAttribute("data-id");

            dataArray.splice(rmId, 1);
            //update localstorage
            localStorage['contactInfo'] = JSON.stringify(dataArray);
            displayContactInfo();
        }
    }

    function displayContactInfo() {
        //look for localstorage key if not present create it
        //if exists load content from LS and loop it on page for div to populate

        if (localStorage['contactInfo'] === undefined) {
            localStorage['contactInfo'] = "[]" //string
        } else {
            dataArray = JSON.parse(localStorage['contactInfo']);
            addBookdiv.innerHTML = '';
            for (var i in dataArray) {
                var str = '<div class="entry">';
                str += '<div class="name"><p>' + dataArray[i].fullname + '</p></div>';
                str += '<div class="email"><p>' + dataArray[i].email + '</p></div>';
                str += '<div class="phone"><p>' + dataArray[i].phone + '</p ></div>';
                str += '<div class="del"><a href="#" class="removeButton" data-id="' + i + '" >Delete</a></div>';
                str += '</div >';
                addBookdiv.innerHTML += str;
            }
        }
    }

    displayContactInfo();
}

Notes:

The read-only localStorage property allows you to access Storage object for the Document‘s origin; the stored data is saved across browser sessions. localStorage is similar to sessionStorage, except that while data stored in localStorage has no expiration time, data stored in sessionStorage gets cleared when the page session ends — that is, when the page is closed.

**The keys and the values are always strings (note that, as with objects, integer keys will be automatically converted to strings).**

Reference : Click Here