Local Storage and Session Storage in JavaScript

US President Donald Trump descended the steps of Air Force One in Beijing on Wednesday evening, greeted with pomp and pageantry ahead of a high-stakes summit with his Chinese counterpart, Xi Jinping.

During his two-day visit, the global superpowers are expected to discuss tariffs, competition over technology, the war in Iran, and America's relationship with Taiwan.

Trump returns to a more assertive China than the one he visited in 2017, as he faces mounting scrutiny over his military campaign in the Middle East.

The trip had originally been scheduled for March but was postponed because of the US and Israel's war in Iran, a conflict that continues to unsettle the global economy.

A decade on, Trump returns to a stronger and more assertive China

JSON & AJAX in JavaScript


JSON and AJAX are two pillars of modern web development.
One is the language of data exchange, and the other is the bridge between browser and server.

Think of it like this:

  • JSON → the package containing information 📦
  • AJAX → the delivery system 🚚

Together, they make websites dynamic, fast, and interactive without refreshing the page.


Part 1 — What is JSON?

Definition

JSON stands for:

JavaScript Object Notation

It is a lightweight format used to store and exchange data between:

  • Browser ↔ Server
  • APIs ↔ Applications
  • Frontend ↔ Backend

Even though it comes from JavaScript, JSON is language-independent and supported by almost every programming language.


Why JSON Was Created

Before JSON, XML was widely used.

XML was:

  • Heavy
  • Complex
  • Verbose

Example XML:

<student>
   <name>Anas</name>
   <age>21</age>
</student>

JSON made the same thing simpler:

{
   "name": "Anas",
   "age": 21
}

Cleaner. Faster. Easier.

That simplicity made JSON the king of APIs.


Structure of JSON

JSON stores data as:

  • Objects
  • Arrays
  • Key-value pairs

JSON Object

{
   "name": "Anas",
   "age": 21,
   "isStudent": true
}

Rules of JSON

1. Keys must be inside double quotes

✅ Correct

{
   "name": "Anas"
}

❌ Wrong

{
   name: "Anas"
}

2. Strings use double quotes

✅ Correct

{
   "city": "Mumbai"
}

3. Data is in key-value pairs

{
   "key": "value"
}

4. Values can be:

  • String
  • Number
  • Boolean
  • Array
  • Object
  • null

Example:

{
   "name": "Anas",
   "age": 21,
   "marks": [90, 85, 88],
   "address": {
      "city": "Mumbai"
   },
   "passed": true
}

JSON vs JavaScript Object

This confuses many beginners.

JavaScript Object

let student = {
   name: "Anas",
   age: 21
};

JSON

{
   "name": "Anas",
   "age": 21
}

Main Difference

JavaScript Object JSON
Used inside JS Used for data transfer
Keys may not need quotes Keys must have quotes
Can contain functions Cannot contain functions

Converting JavaScript Object to JSON

Use:

JSON.stringify()

Example

let student = {
    name: "Anas",
    age: 21
};

let jsonData = JSON.stringify(student);

console.log(jsonData);

Output:

{"name":"Anas","age":21}

Why stringify?

Because servers usually understand text, not JavaScript objects.

So:

Object → JSON String → Server

Converting JSON to JavaScript Object

Use:

JSON.parse()

Example

let data = '{"name":"Anas","age":21}';

let obj = JSON.parse(data);

console.log(obj.name);

Output:

Anas

Real-Life Example of JSON

When you log into a website:

{
   "username": "anas123",
   "token": "abc123xyz"
}

When you order food:

{
   "item": "Burger",
   "price": 250,
   "quantity": 2
}

JSON silently powers almost every modern application.


Part 2 — What is AJAX?

Definition

AJAX stands for:

Asynchronous JavaScript And XML

Ironically, today AJAX mostly uses JSON instead of XML.


What AJAX Does

AJAX allows a webpage to:

✅ Send requests to server
✅ Receive data from server
✅ Update webpage
✅ Without refreshing page


Before AJAX

Every action refreshed the page.

Example:

  1. Click submit
  2. Entire page reloads
  3. Wait again

Slow and annoying.


After AJAX

Only required data changes.

Examples:

  • Instagram likes ❤️
  • Live chat 💬
  • Google search suggestions 🔍
  • YouTube comments
  • Gmail inbox updates

All powered by AJAX.


Understanding “Asynchronous”

Synchronous

Tasks happen one by one.

Task 1 → Finish → Task 2

Asynchronous

Tasks can happen in background.

Request sent →
Continue working →
Response comes later

This prevents the webpage from freezing.


AJAX Working Flow

User Action
    ↓
JavaScript Sends Request
    ↓
Server Processes Request
    ↓
Server Sends Response
    ↓
JavaScript Updates Page

Traditional Page vs AJAX

Traditional

Click → Full Reload → New Page

AJAX

Click → Data Fetch → Update Part Only

Ways to Perform AJAX

There are mainly 3 methods:

  1. XMLHttpRequest (Old)
  2. Fetch API (Modern)
  3. Axios (Library)

1. XMLHttpRequest (Old AJAX Method)

Basic Syntax

let xhr = new XMLHttpRequest();

xhr.open("GET", "data.json");

xhr.send();

Complete Example

data.json

{
   "name": "Anas",
   "course": "JavaScript"
}

JavaScript

let xhr = new XMLHttpRequest();

xhr.open("GET", "data.json", true);

xhr.onload = function () {
    
    if (xhr.status === 200) {
        
        let data = JSON.parse(xhr.responseText);

        console.log(data.name);
    }
};

xhr.send();

Logic Breakdown

Step 1

let xhr = new XMLHttpRequest();

Creates AJAX request object.


Step 2

xhr.open("GET", "data.json", true);

Opens connection.

Parameters

Parameter Meaning
GET Request type
data.json File/API
true Asynchronous

Step 3

xhr.onload = function ()

Runs when response arrives.


Step 4

xhr.status === 200

Checks success.

200 = OK


Step 5

JSON.parse()

Converts JSON text into JavaScript object.


Step 6

xhr.send();

Sends request.


2. Fetch API (Modern AJAX)

Today this is preferred.

Cleaner. Easier. Promise-based.


Basic Fetch Syntax

fetch("data.json")
    .then(response => response.json())
    .then(data => console.log(data));

Complete Example

fetch("data.json")
    .then(function(response) {
        return response.json();
    })
    .then(function(data) {
        console.log(data.name);
        console.log(data.course);
    })
    .catch(function(error) {
        console.log(error);
    });

Logic Flow

Step 1

fetch("data.json")

Sends request.


Step 2

response.json()

Converts response into JavaScript object.


Step 3

.then(data => ...)

Handles successful data.


Step 4

.catch()

Handles errors.


Using Async/Await with Fetch

Modern professional style.


Example

async function getData() {

    try {

        let response = await fetch("data.json");

        let data = await response.json();

        console.log(data);

    } catch(error) {

        console.log(error);
    }
}

getData();

Why async/await is Better

Instead of messy chaining:

.then()
.then()
.then()

It looks synchronous and cleaner.


AJAX Request Types


GET Request

Used to FETCH data.

fetch("users.json")

POST Request

Used to SEND data.

fetch("https://example.com/api", {
    method: "POST",
    headers: {
        "Content-Type": "application/json"
    },
    body: JSON.stringify({
        name: "Anas",
        age: 21
    })
});

Logic of POST Request

headers

Tell server data type.


body

Actual data sent.


JSON.stringify()

Converts object into JSON string.


Real API Example

Using free API:

fetch("https://jsonplaceholder.typicode.com/users")
    .then(response => response.json())
    .then(data => console.log(data));

This returns user data from server.


Example Output

[
   {
      id: 1,
      name: "Leanne Graham"
   }
]

Display API Data in HTML

HTML

<ul id="users"></ul>

JavaScript

fetch("https://jsonplaceholder.typicode.com/users")
    .then(response => response.json())
    .then(data => {

        let users = document.getElementById("users");

        data.forEach(function(user) {

            users.innerHTML += `
                <li>${user.name}</li>
            `;
        });
    });

What Happens Internally

Browser requests API
        ↓
Server sends JSON
        ↓
JavaScript converts JSON
        ↓
HTML updates dynamically

That is modern web development in action.


Common HTTP Status Codes

Code Meaning
200 Success
201 Created
400 Bad Request
401 Unauthorized
404 Not Found
500 Server Error

Common AJAX Errors

1. Network Error

No internet/server issue.


2. Invalid JSON

Broken JSON format.


3. CORS Error

Browser blocks request from another domain.


JSON + AJAX Together

This is the real workflow:

Frontend JavaScript
       ↓
AJAX Request
       ↓
Server/API
       ↓
JSON Response
       ↓
JavaScript Updates UI

Real-World Applications

Application Usage
WhatsApp Web Live messages
Instagram Likes/comments
Amazon Product loading
YouTube Video suggestions
Gmail Inbox updates
Google Maps Dynamic map loading

Mini Project Example

Live Weather App

Flow:

User enters city
       ↓
AJAX fetches weather API
       ↓
API returns JSON
       ↓
JavaScript displays temperature

This single flow powers thousands of real applications.


Important Interview Questions

Difference Between JSON and AJAX?

JSON AJAX
Data format Technique
Stores/transfers data Fetches data
Lightweight text Uses JavaScript

Why JSON is Popular?

  • Lightweight
  • Fast
  • Easy to read
  • Language independent

Why AJAX is Important?

  • Faster user experience
  • No page reload
  • Real-time applications
  • Better performance

Best Practices

Always Handle Errors

.catch(error => console.log(error))

Use async/await

Cleaner and professional.


Validate JSON

Never trust external API blindly.


Avoid Blocking UI

Use asynchronous requests properly.


Final Summary

JSON

  • Data format
  • Lightweight
  • Used in APIs
  • Easy data exchange

AJAX

  • Technique for server communication
  • Updates page without reload
  • Uses asynchronous requests
  • Commonly uses JSON

Golden Analogy

Imagine a restaurant:

  • AJAX = waiter carrying requests/responses 🍽️
  • JSON = food package/data 📦
  • Server = kitchen 👨‍🍳
  • Browser = customer table 🪑

The customer does not rebuild the restaurant every time food arrives.
Only the table updates.

That is exactly how modern websites work.

Error Handling in JavaScript


Error handling in JavaScript is like a safety net in a circus.
Your code walks the rope of logic — error handling prevents the entire system from collapsing when something unexpected happens.

Without error handling:

  • Applications crash
  • Users see blank pages
  • APIs fail silently
  • Debugging becomes painful

With proper error handling:

  • Applications become stable
  • Bugs become easier to track
  • User experience improves
  • Systems become production-ready

1. What is an Error in JavaScript?

An error is a problem that stops the normal execution of a program.

Example:

console.log(userName);

Output:

ReferenceError: userName is not defined

Because userName variable does not exist.


2. Why Error Handling is Important

Imagine:

  • Banking app transferring money
  • Login system authenticating users
  • Payment gateway processing transactions

One small error can break the workflow.

Error handling helps to:

  • Detect problems
  • Prevent crashes
  • Show meaningful messages
  • Recover gracefully

3. Types of Errors in JavaScript


A) Syntax Error

Occurs when code grammar is incorrect.

Example:

if (true {
    console.log("Hello");
}

Output:

SyntaxError: Unexpected token {

Because parenthesis is missing.


B) Reference Error

Occurs when accessing undeclared variables.

Example:

console.log(age);

Output:

ReferenceError: age is not defined

C) Type Error

Occurs when performing invalid operations on data types.

Example:

let num = 10;

num.toUpperCase();

Output:

TypeError: num.toUpperCase is not a function

Because numbers do not have toUpperCase().


D) Range Error

Occurs when value exceeds allowed range.

Example:

let arr = new Array(-1);

Output:

RangeError: Invalid array length

E) Logical Error

Program runs but gives wrong output.

Example:

let total = 10 + "5";

console.log(total);

Output:

105

No crash — but wrong logic.

These are the most dangerous errors.


4. try...catch Statement

Main mechanism for handling errors.


Syntax

try {
    // risky code
}
catch(error) {
    // handle error
}

Example

try {
    console.log(userName);
}
catch(error) {
    console.log("Something went wrong");
}

Output:

Something went wrong

Instead of crashing the application.


5. Understanding the Flow


Step-by-Step Logic

try {
    let result = 10 / 0;
}
catch(error) {
    console.log(error);
}

Flow:

  1. JavaScript enters try
  2. Executes risky code
  3. If error occurs:
    • execution stops inside try
    • control jumps to catch
  4. Error object is stored in parameter

6. The Error Object

The catch(error) parameter contains useful information.


Example

try {
    console.log(data);
}
catch(error) {
    console.log(error.name);
    console.log(error.message);
}

Output:

ReferenceError
data is not defined

Important Properties

Property Meaning
name Type of error
message Error description
stack Error trace

7. finally Block

finally always runs whether error happens or not.


Syntax

try {

}
catch(error) {

}
finally {

}

Example

try {
    console.log("Start");
}
catch(error) {
    console.log(error);
}
finally {
    console.log("Always runs");
}

Output:

Start
Always runs

Real-Life Use

Used for:

  • Closing database connections
  • Stopping loaders
  • Cleaning resources
  • Logging

8. throw Statement

Used to create custom errors.


Syntax

throw error;

Example

let age = 15;

try {
    if(age < 18) {
        throw "You are underage";
    }

    console.log("Access granted");
}
catch(error) {
    console.log(error);
}

Output:

You are underage

9. Throwing Custom Error Objects

Professional approach.


Example

try {
    let password = "123";

    if(password.length < 6) {
        throw new Error("Password too short");
    }
}
catch(error) {
    console.log(error.message);
}

Output:

Password too short

10. Nested try...catch

Possible to place try...catch inside another.


Example

try {

    try {
        console.log(user);
    }
    catch(error) {
        console.log("Inner error handled");
    }

}
catch(error) {
    console.log("Outer error handled");
}

Output:

Inner error handled

11. Error Handling in Functions


Example

function divide(a, b) {

    try {

        if(b === 0) {
            throw new Error("Cannot divide by zero");
        }

        return a / b;

    }
    catch(error) {
        return error.message;
    }

}

console.log(divide(10, 0));

Output:

Cannot divide by zero

12. Error Handling in JSON

Very common in APIs.


Example

let data = '{"name":"Anas"}';

try {

    let result = JSON.parse(data);

    console.log(result.name);

}
catch(error) {
    console.log("Invalid JSON");
}

Invalid JSON Example

let data = '{"name":"Anas"';

JSON.parse(data);

Output:

SyntaxError

13. Asynchronous Error Handling

Very important in modern JavaScript.


A) Promise Error Handling


Example

fetch("wrong-url")

.then(response => response.json())

.catch(error => {
    console.log("Fetch failed");
});

.catch() handles promise errors.


B) async/await Error Handling


Example

async function getData() {

    try {

        let response = await fetch("wrong-url");

        let data = await response.json();

        console.log(data);

    }
    catch(error) {
        console.log("Error fetching data");
    }

}

getData();

14. Real-World Form Validation Example


Example

function validateForm(username) {

    try {

        if(username === "") {
            throw new Error("Username required");
        }

        console.log("Form submitted");

    }
    catch(error) {
        console.log(error.message);
    }

}

validateForm("");

Output:

Username required

15. Best Practices for Error Handling


1. Never Ignore Errors

Bad:

catch(error) {

}

This hides bugs.


2. Show Meaningful Messages

Bad:

Error

Good:

"Invalid email format"

3. Use Custom Errors

Makes debugging easier.


4. Handle Async Errors Properly

Always use:

  • .catch()
  • try...catch with async/await

5. Avoid Overusing try...catch

Use it only around risky code.

Bad:

try {
    let x = 5;
}
catch(error) {

}

No need here.


16. Common Beginner Mistakes


Mistake 1

Using try...catch for syntax errors.

try {
    if(true {
}
catch(error) {
}

Syntax errors occur before execution.


Mistake 2

Forgetting await

try {
    fetch(url);
}
catch(error) {

}

This may not catch async errors.


Mistake 3

Throwing plain strings

Bad:

throw "Error";

Better:

throw new Error("Error");

17. Advanced: Custom Error Classes

Used in large applications.


Example

class ValidationError extends Error {

    constructor(message) {
        super(message);
        this.name = "ValidationError";
    }

}

try {

    throw new ValidationError("Invalid input");

}
catch(error) {

    console.log(error.name);
    console.log(error.message);

}

Output:

ValidationError
Invalid input

18. Difference Between Compile-Time and Runtime Errors

Type Meaning
Compile/Syntax Error Code cannot start
Runtime Error Error during execution

19. Practical Mini Project Example


ATM Withdrawal System

function withdraw(balance, amount) {

    try {

        if(amount > balance) {
            throw new Error("Insufficient balance");
        }

        if(amount <= 0) {
            throw new Error("Invalid amount");
        }

        balance -= amount;

        console.log("Remaining Balance:", balance);

    }
    catch(error) {
        console.log(error.message);
    }

}

withdraw(5000, 7000);

Output:

Insufficient balance

20. Visual Flow of Error Handling

START
   ↓
try block executes
   ↓
Error occurs?
   ↓
YES --------→ catch block runs
   ↓
NO
   ↓
finally block runs
   ↓
END

21. Summary Table

Concept Purpose
try Contains risky code
catch Handles errors
finally Always executes
throw Creates custom error
Error object Stores error details
async catch Handles async failures

Final Thought

A beginner writes code that works.
A professional writes code that survives failure.

Error handling is not merely about fixing bugs —
it is about building resilient systems that continue standing when storms arrive.

In modern software engineering, graceful failure is a mark of mature architecture.

Asynchronous JavaScript


JavaScript is single-threaded, meaning it executes one task at a time.
But modern web applications must handle:

  • API requests
  • Timers
  • Database operations
  • File reading
  • User events
  • Animations

If JavaScript waited for every slow task to finish, the entire webpage would freeze like a locked gate in a storm.

To solve this, JavaScript uses Asynchronous Programming.


1. What is Synchronous JavaScript?

In synchronous code, tasks run line by line.

console.log("Start");

console.log("Middle");

console.log("End");

Output

Start
Middle
End

Each statement waits for the previous one to complete.


2. Problem with Synchronous Code

Imagine downloading data from a server.

console.log("Fetching data...");

// Assume this takes 5 seconds
heavyTask();

console.log("Done");

During those 5 seconds:

  • UI freezes
  • Buttons stop working
  • Website becomes unresponsive

This is bad user experience.


3. What is Asynchronous JavaScript?

Asynchronous JavaScript allows:

“Start a task now, finish it later, and continue executing other code meanwhile.”

Example:

console.log("Start");

setTimeout(() => {
    console.log("Task Finished");
}, 3000);

console.log("End");

Output

Start
End
Task Finished

The timer runs in background while JavaScript continues.


4. How JavaScript Handles Async Operations

JavaScript uses:

  • Call Stack
  • Web APIs
  • Callback Queue
  • Event Loop

These work together like an organized system.


5. The JavaScript Runtime Architecture

Step-by-Step Flow

Call Stack → Web APIs → Callback Queue → Event Loop

(A) Call Stack

The place where functions execute.

Example:

function hello() {
    console.log("Hello");
}

hello();

hello() enters stack → executes → removed.


(B) Web APIs

Provided by browser or Node.js.

Examples:

  • setTimeout
  • fetch
  • DOM events
  • geolocation

These are NOT part of JavaScript itself.


(C) Callback Queue

Completed async tasks wait here.


(D) Event Loop

Checks:

“Is call stack empty?”

If YES → moves callback from queue to stack.


6. Understanding setTimeout()

Syntax

setTimeout(function, delay);

Example:

setTimeout(() => {
    console.log("Hello after 2 seconds");
}, 2000);

Important Logic

Even if delay is 0, it still waits until stack becomes empty.

Example:

console.log("A");

setTimeout(() => {
    console.log("B");
}, 0);

console.log("C");

Output

A
C
B

Because async callbacks always wait for stack clearance.


7. Callbacks in JavaScript

A callback is:

A function passed as an argument to another function.

Example:

function greet(name, callback) {
    console.log("Hello " + name);

    callback();
}

function bye() {
    console.log("Goodbye");
}

greet("Anas", bye);

Output

Hello Anas
Goodbye

8. Asynchronous Callback Example

setTimeout(() => {
    console.log("Data Loaded");
}, 2000);

The function executes later.


9. Callback Hell

When many async operations depend on each other.

Example:

setTimeout(() => {
    console.log("Step 1");

    setTimeout(() => {
        console.log("Step 2");

        setTimeout(() => {
            console.log("Step 3");
        }, 1000);

    }, 1000);

}, 1000);

This pyramid structure becomes difficult to manage.

Problems:

  • Hard to read
  • Hard to debug
  • Hard to maintain

This is called:

“Callback Hell” or “Pyramid of Doom”


10. Promises in JavaScript

Promises were introduced to solve callback hell.

A Promise represents:

Future Success OR Failure

11. Promise States

A Promise has 3 states:

State Meaning
Pending Still running
Fulfilled Success
Rejected Failed

12. Creating a Promise

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

    let success = true;

    if(success) {
        resolve("Task completed");
    } else {
        reject("Task failed");
    }

});

13. Consuming Promises

Using .then() and .catch()

promise
    .then((result) => {
        console.log(result);
    })
    .catch((error) => {
        console.log(error);
    });

14. Real Example of Promise

function fetchData() {

    return new Promise((resolve, reject) => {

        setTimeout(() => {
            resolve("Data received from server");
        }, 2000);

    });

}

fetchData()
    .then((data) => {
        console.log(data);
    });

Output after 2 seconds

Data received from server

15. Promise Chaining

fetchData()
    .then((data) => {
        console.log(data);
        return "Next Step";
    })
    .then((msg) => {
        console.log(msg);
    });

16. Handling Errors

fetchData()
    .then((data) => {
        console.log(data);
    })
    .catch((error) => {
        console.log(error);
    });

17. Async and Await

async/await makes asynchronous code look synchronous and cleaner.

Introduced in ES8.


18. Async Function

async function hello() {
    return "Hello";
}

Async functions automatically return promises.


19. Await Keyword

await pauses execution until promise resolves.

Example:

function fetchData() {

    return new Promise((resolve) => {

        setTimeout(() => {
            resolve("Server Data");
        }, 2000);

    });

}

async function getData() {

    const data = await fetchData();

    console.log(data);
}

getData();

Output after 2 seconds

Server Data

20. Error Handling with Try-Catch

async function getData() {

    try {

        const data = await fetchData();

        console.log(data);

    } catch(error) {

        console.log(error);

    }

}

21. Fetch API

Used to request data from servers/APIs.


Basic Fetch Example

fetch("https://jsonplaceholder.typicode.com/users")
    .then((response) => {
        return response.json();
    })
    .then((data) => {
        console.log(data);
    });

22. Fetch Using Async/Await

async function getUsers() {

    const response = await fetch(
        "https://jsonplaceholder.typicode.com/users"
    );

    const data = await response.json();

    console.log(data);
}

getUsers();

23. Why Async/Await is Better

Callback Promise Async/Await
Complex Better Cleanest
Nested Flat Simple
Hard debugging Easier Very easy
Less readable Good Excellent

24. Parallel Async Operations

Promise.all()

Runs multiple promises together.

const p1 = Promise.resolve("A");
const p2 = Promise.resolve("B");
const p3 = Promise.resolve("C");

Promise.all([p1, p2, p3])
    .then((result) => {
        console.log(result);
    });

Output

["A", "B", "C"]

25. Promise.race()

Returns first completed promise.

Promise.race([p1, p2, p3])
    .then((result) => {
        console.log(result);
    });

26. Microtasks vs Macrotasks

Very important interview topic.


Macrotasks

Examples:

  • setTimeout
  • setInterval

Microtasks

Examples:

  • Promise
  • queueMicrotask

Microtasks execute before macrotasks.


Example

console.log("Start");

setTimeout(() => {
    console.log("Timeout");
}, 0);

Promise.resolve().then(() => {
    console.log("Promise");
});

console.log("End");

Output

Start
End
Promise
Timeout

Because:

Microtask Queue > Macrotask Queue

Priority is given to microtasks.


27. Event Loop Visualization

1. Execute Call Stack
2. Check Microtask Queue
3. Execute all Microtasks
4. Check Macrotask Queue
5. Repeat forever

This endless cycle powers asynchronous JavaScript.


28. Real-World Use Cases

Feature Async Used?
API Calls Yes
Chat Apps Yes
Live Notifications Yes
Video Streaming Yes
File Uploads Yes
Database Queries Yes

Without async programming, modern web apps cannot exist.


29. Common Interview Questions

Q1: Is JavaScript synchronous or asynchronous?

JavaScript is:

Single-threaded and synchronous by nature

But it can handle async operations using:

  • Event Loop
  • Web APIs
  • Callbacks
  • Promises

Q2: Difference between callback and promise?

Callback Promise
Function-based Object-based
Causes nesting Cleaner
Hard error handling Better error handling

Q3: Difference between async/await and promise?

async/await is syntactic sugar over promises.

Promises still work underneath.


30. Complete Real-World Example

function loginUser() {

    return new Promise((resolve) => {

        setTimeout(() => {
            resolve("User Logged In");
        }, 2000);

    });

}

function getProfile() {

    return new Promise((resolve) => {

        setTimeout(() => {
            resolve("Profile Data");
        }, 1000);

    });

}

async function app() {

    console.log("Loading...");

    const user = await loginUser();

    console.log(user);

    const profile = await getProfile();

    console.log(profile);

    console.log("Application Ready");

}

app();

Output Flow

Loading...

(after 2 sec)
User Logged In

(after 1 sec)
Profile Data

Application Ready

Final Core Understanding

Asynchronous JavaScript is built on:

1. Call Stack
2. Web APIs
3. Callback Queue
4. Event Loop
5. Promises
6. Async/Await

Master these deeply, and JavaScript begins to feel less like chaos and more like rhythm — like caravans moving through time without blocking each other’s path.

ES6 in JavaScript (ECMAScript 2015)


ES6 — also called ECMAScript 2015 — was a revolutionary update to JavaScript.
Before ES6, JavaScript felt like a village road. After ES6, it became an express highway for modern web development.

It introduced cleaner syntax, powerful features, better readability, and professional coding standards.

Today, frameworks like React, Node.js, and Vue.js heavily rely on ES6 features.


Why ES6 Was Introduced

Old JavaScript had problems:

  • Difficult syntax
  • Repeated code
  • Confusing variable scope
  • Weak support for modular programming
  • Callback-heavy coding style

ES6 solved these with modern tools.


Major ES6 Features

We’ll cover:

  1. let and const
  2. Arrow Functions
  3. Template Literals
  4. Default Parameters
  5. Destructuring
  6. Spread Operator
  7. Rest Parameters
  8. Enhanced Object Literals
  9. Classes
  10. Modules
  11. Promises
  12. for...of
  13. Map and Set

1. let and const

Before ES6, variables were declared using var.

var name = "Anas";

Problem with var:

  • Function scoped
  • Can be redeclared
  • Causes bugs

let

let is block scoped.

let age = 20;

if (true) {
    let age = 25;
    console.log(age);
}

console.log(age);

Output

25
20

Logic

The variable inside {} is different from the outer variable.


const

Used for constant values.

const pi = 3.14;

Cannot be reassigned.

const pi = 3.14;
pi = 3.1415;

Error

Assignment to constant variable

var vs let vs const

Feature var let const
Scope Function Block Block
Redeclare Yes No No
Reassign Yes Yes No

2. Arrow Functions

Arrow functions provide shorter syntax.


Traditional Function

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

Arrow Function

const add = (a, b) => {
    return a + b;
};

Shorter Version

const add = (a, b) => a + b;

Output

console.log(add(5, 3));
8

Why Arrow Functions Are Important

They:

  • Reduce code
  • Improve readability
  • Preserve this

Example

const person = {
    name: "Anas",

    greet: function () {
        setTimeout(() => {
            console.log("Hello " + this.name);
        }, 1000);
    }
};

person.greet();

Output

Hello Anas

Arrow function keeps the object's this.


3. Template Literals

Before ES6:

let name = "Anas";
console.log("Hello " + name);

ES6 Template Literals

Use backticks `

let name = "Anas";

console.log(`Hello ${name}`);

Output

Hello Anas

Multi-line Strings

let text = `
This is line 1
This is line 2
`;

console.log(text);

4. Default Parameters

Old way:

function greet(name) {
    name = name || "Guest";
    console.log(name);
}

ES6 Way

function greet(name = "Guest") {
    console.log(name);
}

greet();

Output

Guest

5. Destructuring

Extract values easily.


Array Destructuring

const colors = ["red", "green", "blue"];

const [a, b, c] = colors;

console.log(a);
console.log(b);

Output

red
green

Object Destructuring

const student = {
    name: "Anas",
    age: 20
};

const { name, age } = student;

console.log(name);

Output

Anas

Why Destructuring Matters

Used heavily in:

  • React
  • APIs
  • JSON handling
  • Function parameters

6. Spread Operator (...)

Spread expands values.


Arrays

const arr1 = [1, 2];
const arr2 = [3, 4];

const result = [...arr1, ...arr2];

console.log(result);

Output

[1, 2, 3, 4]

Objects

const user = {
    name: "Anas"
};

const updatedUser = {
    ...user,
    city: "Mumbai"
};

console.log(updatedUser);

Output

{
  name: "Anas",
  city: "Mumbai"
}

7. Rest Parameters

Collect multiple values into one array.

function sum(...numbers) {
    console.log(numbers);
}

sum(1, 2, 3, 4);

Output

[1, 2, 3, 4]

Real Example

function total(...nums) {
    return nums.reduce((a, b) => a + b);
}

console.log(total(10, 20, 30));

Output

60

8. Enhanced Object Literals


Old Way

const name = "Anas";

const user = {
    name: name
};

ES6 Way

const name = "Anas";

const user = {
    name
};

console.log(user);

Output

{ name: "Anas" }

Short Method Syntax

const user = {
    greet() {
        console.log("Hello");
    }
};

user.greet();

9. Classes

ES6 introduced cleaner OOP syntax.


Example

class Student {

    constructor(name, age) {
        this.name = name;
        this.age = age;
    }

    intro() {
        console.log(`My name is ${this.name}`);
    }
}

const s1 = new Student("Anas", 20);

s1.intro();

Output

My name is Anas

Inheritance

class Animal {
    speak() {
        console.log("Animal speaks");
    }
}

class Dog extends Animal {
    bark() {
        console.log("Dog barks");
    }
}

const d = new Dog();

d.speak();
d.bark();

10. Modules

Modules split code into separate files.


Export

export const name = "Anas";

Import

import { name } from "./file.js";

console.log(name);

Benefits of Modules

  • Cleaner codebase
  • Reusable functions
  • Better scalability
  • Industry standard architecture

11. Promises

Promises handle asynchronous tasks.

Examples:

  • API calls
  • Database queries
  • File loading

Basic Promise

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

    let success = true;

    if (success) {
        resolve("Task completed");
    } else {
        reject("Task failed");
    }
});

promise
    .then(result => console.log(result))
    .catch(error => console.log(error));

Output

Task completed

Promise States

State Meaning
Pending Waiting
Resolved Success
Rejected Failed

12. for...of Loop

Used for arrays and iterable objects.

const fruits = ["apple", "banana", "mango"];

for (const fruit of fruits) {
    console.log(fruit);
}

Output

apple
banana
mango

13. Map

Stores key-value pairs.

const map = new Map();

map.set("name", "Anas");
map.set("age", 20);

console.log(map.get("name"));

Output

Anas

14. Set

Stores unique values.

const numbers = new Set([1, 2, 2, 3, 3]);

console.log(numbers);

Output

Set(3) {1, 2, 3}

Real-Life Importance of ES6

ES6 is everywhere:

Technology Uses ES6
React Yes
Node.js Yes
Express.js Yes
Vue.js Yes
Angular Yes

Without ES6, modern JavaScript development becomes difficult.


Mini Real Project Example

const students = [
    { name: "Anas", marks: 90 },
    { name: "Ali", marks: 80 },
    { name: "Zaid", marks: 70 }
];

const result = students
    .filter(student => student.marks >= 80)
    .map(student => `${student.name} passed`);

console.log(result);

Output

["Anas passed", "Ali passed"]

ES6 Interview Questions


Difference between let and const?

  • let can change
  • const cannot change

What is destructuring?

Extracting values from arrays/objects into variables.


What is spread operator?

Expands array/object elements.


Difference between spread and rest?

Spread Rest
Expands values Collects values

Why use arrow functions?

  • Short syntax
  • Cleaner code
  • Lexical this

Final Summary

ES6 modernized JavaScript completely.

Core strengths:

  • Cleaner syntax
  • Better readability
  • Modular programming
  • Easier async handling
  • Powerful array/object manipulation

If old JavaScript was handwritten paperwork, ES6 became a smart digital workflow system — efficient, scalable, elegant.

Mastering ES6 is not optional anymore for a JavaScript developer. It is the foundation stone upon which modern frontend and backend ecosystems stand.

Forms and Validation in JavaScript


Forms are the bridge between the user and the application.
A website without forms is like a masjid without doors — beautiful perhaps, but no one can enter and interact.

JavaScript gives life to forms:

  • taking input,
  • checking correctness,
  • preventing wrong submissions,
  • improving user experience,
  • and protecting data integrity.

1. What is a Form?

A form is an HTML structure used to collect user data.

Example:

<form>
    <input type="text" placeholder="Enter Name">
    <button>Submit</button>
</form>

Forms can collect:

  • Name
  • Email
  • Password
  • Phone number
  • Feedback
  • Login details
  • Payment info

2. Why Validation is Important?

Validation means checking whether user input is correct before sending data.

Without validation:

  • Empty fields may be submitted
  • Invalid email addresses may enter database
  • Weak passwords may reduce security
  • Wrong data may break the system

Validation ensures: ✅ Accuracy
✅ Security
✅ Better UX
✅ Clean database


3. Types of Validation

There are mainly 2 types:

Type Description
Client-side Validation Done in browser using JavaScript
Server-side Validation Done on server/backend

JavaScript handles:

Client-side validation

But remember:

Client-side validation improves experience,
Server-side validation ensures security.

Never trust only frontend validation.


4. Basic HTML Form Structure

<form id="myForm">
    
    <label>Name:</label>
    <input type="text" id="name">

    <br><br>

    <label>Email:</label>
    <input type="email" id="email">

    <br><br>

    <button type="submit">Submit</button>

</form>

5. Accessing Form Elements in JavaScript

let form = document.getElementById("myForm");

let nameInput = document.getElementById("name");

let emailInput = document.getElementById("email");

6. Form Submit Event

When user clicks submit button, form fires submit event.

form.addEventListener("submit", function() {
    console.log("Form Submitted");
});

7. Preventing Default Submission

Normally forms reload the page.

JavaScript can stop that using:

event.preventDefault();

Example:

form.addEventListener("submit", function(event) {

    event.preventDefault();

    console.log("Submission stopped");

});

Logic Behind preventDefault()

Default behavior of form:

  1. Submit data
  2. Reload page

But while validating:

  • we first check data,
  • then decide whether submission should happen.

So we stop automatic behavior temporarily.


8. Simple Empty Field Validation

Example:

form.addEventListener("submit", function(event) {

    event.preventDefault();

    let name = nameInput.value;

    if(name === "") {
        alert("Name is required");
    } else {
        alert("Form submitted successfully");
    }

});

Logic

User clicks submit
        ↓
Get input value
        ↓
Check if empty
        ↓
If empty → show error
Else → success

9. Using trim()

Users may enter spaces.

let name = nameInput.value.trim();

Example:

if(name === "") {
    alert("Please enter valid name");
}

10. Email Validation

Simple Validation

if(email === "") {
    alert("Email required");
}

11. Regular Expressions (Regex)

Regex checks patterns.

Email pattern example:

let pattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

Email Validation Example

let email = emailInput.value.trim();

let pattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

if(pattern.test(email)) {
    alert("Valid Email");
} else {
    alert("Invalid Email");
}

Logic of Regex

something@something.something

Checks:

  • must contain @
  • must contain .
  • no spaces

12. Password Validation

Example requirements:

  • Minimum 8 characters
  • Contains uppercase
  • Contains lowercase
  • Contains number

Example

let password = passwordInput.value;

if(password.length < 8) {
    alert("Password too short");
}

Strong Password Regex

let pattern =
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$/;

Explanation

Part Meaning
(?=.*[a-z]) lowercase required
(?=.*[A-Z]) uppercase required
(?=.*\d) number required
{8,} minimum 8 chars

13. Full Form Validation Example

HTML

<form id="registerForm">

    <input type="text" id="username" placeholder="Username">
    <br><br>

    <input type="email" id="email" placeholder="Email">
    <br><br>

    <input type="password" id="password" placeholder="Password">
    <br><br>

    <button type="submit">Register</button>

</form>

JavaScript

let form = document.getElementById("registerForm");

form.addEventListener("submit", function(event) {

    event.preventDefault();

    let username =
        document.getElementById("username").value.trim();

    let email =
        document.getElementById("email").value.trim();

    let password =
        document.getElementById("password").value.trim();

    if(username === "") {
        alert("Username required");
        return;
    }

    let emailPattern =
        /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

    if(!emailPattern.test(email)) {
        alert("Invalid email");
        return;
    }

    if(password.length < 8) {
        alert("Password must be 8 characters");
        return;
    }

    alert("Registration successful");

});

Step-by-Step Logic

Submit Clicked
      ↓
Stop page reload
      ↓
Get all values
      ↓
Validate username
      ↓
Validate email
      ↓
Validate password
      ↓
If all correct → success

14. Showing Error Messages in Page

Instead of alerts:

HTML

<p id="error"></p>

JavaScript

let error = document.getElementById("error");

error.textContent = "Invalid email";

15. Styling Errors

error.style.color = "red";

16. Real-Time Validation

Validation while typing.

Example:

emailInput.addEventListener("input", function() {

    console.log(emailInput.value);

});

Real-Time Email Checker

emailInput.addEventListener("input", function() {

    let pattern =
        /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

    if(pattern.test(emailInput.value)) {
        emailInput.style.border = "2px solid green";
    } else {
        emailInput.style.border = "2px solid red";
    }

});

17. Confirm Password Validation

if(password !== confirmPassword) {
    alert("Passwords do not match");
}

18. Number Validation

let age = ageInput.value;

if(age < 18) {
    alert("You must be adult");
}

19. Checkbox Validation

Example:

<input type="checkbox" id="terms">
if(!terms.checked) {
    alert("Accept terms first");
}

20. Radio Button Validation

let gender =
document.querySelector('input[name="gender"]:checked');

if(gender === null) {
    alert("Select gender");
}

21. Select Dropdown Validation

if(country.value === "") {
    alert("Select country");
}

22. Form Reset

form.reset();

23. Built-in HTML Validation

HTML itself provides validation.

Example:

<input type="email" required>

Useful HTML Validation Attributes

Attribute Purpose
required field mandatory
minlength minimum length
maxlength maximum length
pattern regex pattern
min minimum value
max maximum value

Example

<input type="password"
       minlength="8"
       required>

24. Custom Validation vs HTML Validation

HTML Validation JavaScript Validation
Simple Powerful
Limited Flexible
Less control Full control

Best practice: ✅ Use both together


25. Common Validation Mistakes

1. Forgetting preventDefault()

Form reloads unexpectedly.


2. Not using trim()

Spaces bypass validation.


3. Weak regex patterns

Bad validation logic.


4. Only frontend validation

Security risk.


26. Real World Example — Login System

User enters:
Email + Password
        ↓
JavaScript checks format
        ↓
If valid:
Send to server
        ↓
Server verifies database
        ↓
Login success/failure

27. Best Practices

✅ Keep validation user-friendly

Bad:

Error 404 validation mismatch

Good:

Please enter valid email

✅ Validate early

Real-time validation improves UX.


✅ Never trust frontend alone

Always validate backend too.


✅ Show specific errors

Tell user exactly what is wrong.


28. Mini Project Example

Live Registration Form

<!DOCTYPE html>
<html>
<head>
    <title>Form Validation</title>
</head>
<body>

<form id="form">

    <input type="text" id="name" placeholder="Name">
    <br><br>

    <input type="email" id="email" placeholder="Email">
    <br><br>

    <input type="password" id="password" placeholder="Password">
    <br><br>

    <button type="submit">Submit</button>

</form>

<p id="message"></p>

<script>

let form = document.getElementById("form");

let message = document.getElementById("message");

form.addEventListener("submit", function(event) {

    event.preventDefault();

    let name =
        document.getElementById("name").value.trim();

    let email =
        document.getElementById("email").value.trim();

    let password =
        document.getElementById("password").value.trim();

    if(name === "") {
        message.textContent = "Name required";
        return;
    }

    let pattern =
        /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

    if(!pattern.test(email)) {
        message.textContent = "Invalid email";
        return;
    }

    if(password.length < 8) {
        message.textContent =
            "Password must be at least 8 characters";
        return;
    }

    message.style.color = "green";
    message.textContent =
        "Form submitted successfully";

});

</script>

</body>
</html>

Final Understanding

Forms are about:

  • collecting data,
  • validation is about protecting quality.

JavaScript acts like a gatekeeper:

Wrong input → stop
Correct input → allow

A wise developer never lets bad data enter the system.

Because in software engineering:

“Clean input creates clean systems.”

And most bugs begin not in complex algorithms —
but in unchecked user input.