# Javascript day2

### **1.** `forEach` Method

* The `forEach` method is used to execute a function on each element of an array.
    
* It is typically used for performing side effects, like logging or updating external variables.
    
* It **does not return** a new array and instead returns `undefined`.
    
* ```plaintext
      array.forEach(callback(currentValue, index, array), thisArg)
    ```
    
    * **callback**: Function to execute for each element.
        
        * **currentValue**: The current element being processed.
            
        * **index** (optional): The index of the current element.
            
        * **array** (optional): The array `forEach` is called upon.
            
    * **thisArg** (optional): Value to use as `this` when executing the callback.
        
    

```plaintext
const numbers = [1, 2, 3, 4, 5];

numbers.forEach((num, index) => {
  console.log(`Index: ${index}, Value: ${num}`);
});
```

### `map` Method

* The `map` method is used to create a **new array** by applying a function to each element of the original array.
    
* It is used for data transformation and does not mutate the original array.
    
* ```plaintext
      const newArray = array.map(callback(currentValue, index, array), thisArg)
    ```
    
    * **callback**: Function to execute on each element.
        
        * **currentValue**: The current element being processed.
            
        * **index** (optional): The index of the current element.
            
        * **array** (optional): The array `map` is called upon.
            
    * **thisArg** (optional): Value to use as `this` when executing the callback.
        
    

```plaintext
const numbers = [1, 2, 3, 4, 5];

// Squaring each number
const squaredNumbers = numbers.map(num => num * num);

console.log(squaredNumbers);
```

### `reduce` Method

* The `reduce` method is used to apply a function to an accumulator and each element in the array to reduce it to a single value.
    
* It is often used for summing up numbers, concatenating strings, or flattening arrays.
    

```plaintext
const result = array.reduce(callback(accumulator, currentValue, index, array), initialValue)
```

* **callback**: Function executed on each element.
    
    * **accumulator**: The accumulated result of the callback function.
        
    * **currentValue**: The current element being processed.
        
    * **index** (optional): The index of the current element.
        
    * **array** (optional): The array `reduce` is called upon.
        
* **initialValue** (optional): Value to use as the first argument to the first call of the callback.
    

```plaintext
const numbers = [1, 2, 3, 4, 5];

// Summing all numbers
const sum = numbers.reduce((acc, num) => acc + num, 0);

console.log(sum);
```

### **What is JSON?**

**JSON** (JavaScript Object Notation) is a lightweight data-interchange format that is easy for humans to read and write and easy for machines to parse and generate. It is commonly used for exchanging data between a client and a server in web applications.

---

### **Key Characteristics of JSON**

1. **Data Representation**:
    
    * JSON represents data as key-value pairs.
        
    * Keys are strings, and values can be strings, numbers, objects, arrays, `true`, `false`, or `null`.
        
2. **Structure**:
    
    * JSON data can be structured as:
        
        * An **object**: `{ "key": "value" }`
            
        * An **array**: `[ { "key": "value" }, { "key": "value" } ]`
            
3. **Text-Based**:
    
    * JSON is a plain text format, making it language-independent.
        
4. **Used in APIs**:
    
    * JSON is widely used for transmitting structured data over networks.
        

---

### **JSON Syntax**

* JSON objects are enclosed in curly braces `{}`.
    
* Key-value pairs are separated by colons `:`.
    
* Multiple key-value pairs are separated by commas `,`.
    
* Strings must be in double quotes `"`.
    

#### Example of JSON Data

```plaintext
{
  "name": "John Doe",
  "age": 30,
  "isStudent": false,
  "skills": ["JavaScript", "Python", "Django"],
  "address": {
    "street": "123 Main St",
    "city": "New York",
    "zip": "10001"
  }
}
```

---

JavaScript is single-threaded by nature, meaning it can execute one task at a time. To handle multiple tasks efficiently, it uses **asynchronous programming** to perform long-running operations (e.g., API calls, file I/O) without blocking the main thread.

### **Key Concepts of Asynchronous Programming**

1. **Synchronous vs Asynchronous**:
    
    * **Synchronous**: Code is executed line by line, and each line must finish before the next starts.
        
    * **Asynchronous**: Code allows other tasks to run while waiting for a longer process to complete.
        
2. **Callbacks**:
    
    * A function passed as an argument to another function and executed later.
        
    * Common in earlier implementations of async programming but can lead to "callback hell."
        
    
    Example:
    
    ```plaintext
    javascriptCopy codesetTimeout(() => {
      console.log('Hello after 2 seconds');
    }, 2000);
    ```
    
    **Introduce Promises**:
    
3. ```plaintext
     const fetchData = new Promise((resolve, reject) => {
       setTimeout(() => {
         resolve("Data fetched!");
       }, 2000);
     });
     
     fetchData.then(data => console.log(data));
    ```
    
    * Explain how Promises handle asynchronous results with `.then()` and `.catch()`.
        
    
    ### **Understanding Promises, Async/Await, and Fetching Data**
    
    Let's break things down into simple steps and examples to explain how Promises, Async/Await, and API fetching work.
    
    ---
    
    ### **1\. Promises in Simple Terms**
    
    A **Promise** is like a promise someone makes to you. They say, "I will give you something in the future, but I don't know when." The Promise can either:
    
    * **Fulfill** (complete successfully).
        
    * **Reject** (fail for some reason).
        
    
    ### **Promise Example**
    
    Imagine you're asking a friend to get you a book:
    
    ```c
    function getBook() {
      return new Promise((resolve, reject) => {
        const isAvailable = true; // Simulate the book being available or not
    
        setTimeout(() => {
          if (isAvailable) {
            resolve("Book is available!");  // Success
          } else {
            reject("Book is out of stock!"); // Failure
          }
        }, 2000);  // Simulate waiting for 2 seconds
      });
    }
    
    getBook()
      .then((message) => {
        console.log(message);  // If the Promise is resolved
      })
      .catch((error) => {
        console.error(error);  // If the Promise is rejected
      });
    ```
    
    ### **Explanation of the Example:**
    
    * `getBook()` returns a Promise.
        
    * After 2 seconds, it either resolves with `"Book is available!"` (if `isAvailable` is `true`), or it rejects with `"Book is out of stock!"`.
        
    * `.then()` is used to handle the result if the Promise is fulfilled.
        
    * `.catch()` is used to handle errors if the Promise is rejected.
        
    
    ### **Output if the book is available**:
    
    ```plaintext
     codeBook is available!
    ```
    
    Here's how you can rewrite the `getBook` example using `async` and `await`:
    
    ### **Using** `async` and `await`
    
    ```c
     function getBook() {
      return new Promise((resolve, reject) => {
        const isAvailable = true; // Simulate the book being available or not
    
        setTimeout(() => {
          if (isAvailable) {
            resolve("Book is available!");  // Success
          } else {
            reject("Book is out of stock!"); // Failure
          }
        }, 2000);  // Simulate waiting for 2 seconds
      });
    }
    
    // Using async/await to call the getBook function
    async function checkBookAvailability() {
      try {
        const message = await getBook();  // Wait for the getBook promise to resolve
        console.log(message);  // If the Promise is resolved
      } catch (error) {
        console.error(error);  // If the Promise is rejected
      }
    }
    
    checkBookAvailability();  // Call the function that handles async/await
    ```
    
    ### **Explanation:**
    
    1. `async function checkBookAvailability()`:
        
        * The `checkBookAvailability` function is marked as `async`, which means it will return a **Promise**.
            
        * Inside this function, we use `await` to wait for the `getBook()` Promise to resolve or reject.
            
    2. `await getBook()`:
        
        * The `await` keyword pauses the execution of the code until `getBook()` resolves or rejects.
            
        * If the Promise is resolved (`resolve("Book is available!")`), the `message` is logged.
            
        * If the Promise is rejected (`reject("Book is out of stock!")`), the error is caught by the `catch()` block and logged.
            
    3. **Error Handling**:
        
        * The `try...catch` block is used to handle any errors. If the Promise rejects, the `catch` block is triggered to handle the error.
            
    
    ---
    
    ### **Output (if the book is available)**:
    
    ```plaintext
    Book is available!
    ```
    
    ---
    
    ### **Output (if the book is out of stock)**:
    
    ```plaintext
    Book is out of stock!
    ```
    
    ---
    
    ### **Key Differences:**
    
    * **Using Promises**: We chain `.then()` and `.catch()` to handle success or failure.
        
    * **Using Async/Await**: We write cleaner, more synchronous-looking code using `await` to wait for the Promise to resolve and handle errors with `try...catch`.
        
    
    ### **Understanding DOM Manipulation and Creating a Basic Project**
    
    The **DOM (Document Object Model)** is like the blueprint of an HTML page. It represents the structure of the webpage, where each element (like a `<div>`, `<p>`, or `<button>`) is an object. You can use JavaScript to change, remove, or add elements in the DOM.
    
    ### **Basic Concepts of DOM Manipulation:**
    
    1. **Selecting Elements**: To manipulate an element, you first need to select it.
        
        * `document.getElementById("id")`: Selects an element by its ID.
            
        * `document.getElementsByClassName("class")`: Selects elements by their class name.
            
        * `document.querySelector("selector")`: Selects the first element that matches the given CSS selector.
            
        * `document.querySelectorAll("selector")`: Selects all elements that match the given CSS selector.
            
    2. **Changing Content or Attributes**:
        
        * `.innerText` or `.textContent`: Change the text inside an element.
            
        * `.innerHTML`: Change the HTML content inside an element.
            
        * `.style`: Change the styles (e.g., color, font size) of an element.
            
        * `.setAttribute()`: Change an attribute of an element (like the `href` of a link).
            
    3. **Creating or Removing Elements**:
        
        * `document.createElement()`: Create a new HTML element.
            
        * `appendChild()`: Add a new child element to an existing element.
            
        * `removeChild()`: Remove a child element from its parent.
            
    
    ### **Simple DOM Manipulation Project: Change Background Color Using Multiple Options**
    
    Here’s a simple project where the user can click on different buttons to change the background color to a specific color based on the button clicked.
    
    ### **HTML (index.html)**
    
    ```c
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Background Color Changer</title>
    </head>
    <body>
    
      <h1>Click a button to change the background color!</h1>
    
      <!-- Buttons to change background color -->
      <button class="color-btn" data-color="red">Red</button>
      <button class="color-btn" data-color="green">Green</button>
      <button class="color-btn" data-color="blue">Blue</button>
      <button class="color-btn" data-color="yellow">Yellow</button>
      <button class="color-btn" data-color="purple">Purple</button>
    
      <script src="script.js"></script>
    </body>
    </html>
    ```
    
    ### **JavaScript (script.js)**
    
    ```c
    // Get all the buttons with the class "color-btn"
    const buttons = document.querySelectorAll('.color-btn');
    
    // Function to change background color based on the clicked button
    function changeBackgroundColor(event) {
      // Get the color from the data-color attribute of the clicked button
      const color = event.target.getAttribute('data-color');
    
      // Change the background color of the body
      document.body.style.backgroundColor = color;
    }
    
    // Add an event listener to each button
    buttons.forEach(button => {
      button.addEventListener('click', changeBackgroundColor);
    });
    ```
    
    ### **How This Works:**
    
    1. **HTML Structure**:
        
        * There are multiple buttons, each with the class `color-btn`.
            
        * Each button has a `data-color` attribute that holds the color value that will be applied to the background when clicked.
            
    2. **JavaScript Logic**:
        
        * **Selecting the Buttons**: We use `document.querySelectorAll('.color-btn')` to select all buttons with the `color-btn` class.
            
        * **Adding Event Listeners**: We loop over all the buttons and add an `eventListener` for the `click` event. When a button is clicked, the `changeBackgroundColor` function is triggered.
            
        * **Changing the Background Color**: The color is retrieved from the `data-color` attribute of the button that was clicked ([`event.target`](http://event.target)`.getAttribute('data-color')`), and the background color of the page is updated accordingly ([`document.body.style`](http://document.body.style)`.backgroundColor`).
            
    
    ### **What Happens:**
    
    * When a user clicks on any of the buttons (Red, Green, Blue, Yellow, Purple), the background color of the page changes to the corresponding color.
        
    
    ### **Learning Points for Students:**
    
    1. **DOM Selection**: Using `querySelectorAll()` to select multiple elements with the same class name.
        
    2. **Event Handling**: Attaching event listeners to multiple buttons using `forEach()` loop.
        
    3. **Custom Data Attributes**: Using `data-*` attributes to store values (like colors) that can be accessed and used in JavaScript.
        
    4. **Dynamic Style Manipulation**: Changing the page's background color by modifying the `style.backgroundColor` property.
        
    
    ---
