How Redux Saga Works ?

Redux Saga works as a middleware layer in a Redux Application that intercepts specific dispatched actions to manage complex asynchronous operations and side effects

It acts like a separate background thread that use ES6 Generator Functions (function*) to seamlessly pause, resume and cancel asynchronous operations without blocking the main UI thread.

The Redux Saga Architecture

The entire operational flow relies on three interconnected components moving data through the Redux state ecosystem:

  1. Middleware: Sits between the dispatched action and the reducer. It listens to every action going through the Redux store.
  2. Watcher Sagas: Specialized generator functions that constantly monitor the redux store for specific action types. When a targeted action is found, the watcher triggers a Worker Saga.
  3. Worker Sagas: Generator functions that execute the actual side effects (like handling an API fetch request or localized data manipulation).

UI Component ==> (Dispatches Action) ==> [Redux Saga Middleware] ==>(intercepts & Triggers) ==> [Watcher Saga] ==> (Spawns / Calls) ===> [ Worker Saga – executes API / Side Effects] ==> (yields Result Action) ==> [Reducer – Receives Action] ==> [New State] ==> [UI Component Updates]

Step-by-Step Execution workflow :

To understand how it functions at runtime, follow this sequence:

  1. User Triggers : A user clicks a button in the React UI layer, which dispatches a tracking action like FETCH_USER_REQUEST.
  2. Interception: The Redux Saga Middleware catches this action before it mutates state or reaches the reducer.
  3. Execution: The Watcher Saga detects FETCH_USER_REQUEST and fires off the corresponding Worker Saga.
  4. Suspension (The Generator Magic): The Worker Saga runs until it hits a yield keyword paired with an Effect(Example: yield call(fetchUserApi)). The Saga temporarily pauses here.
  5. Resolution: The middleware executes the asynchronous request under the hood. once the Promise resolves, the middleware automatically wakes up the Saga and passes the resolved data back.
  6. Dispatch: The Worker Saga resumes and dispatches a success or failure outcome action to the Reducers via a put effect (Example: yield put({type: ‘FETCH_SUCCESS’, data}))
  7. State Mutation: The Reducer catches the success action, modifies the application state, and updates the view layer.

Core Redux Saga Effects

Rather than executing functions directly, Sagas use Effects – plain JavaScript objects containing declarative instructions for the middleware to process.

  • takeEvery(): Starts a new worker instance on every matching action dispatched (concurrent requests).
  • takeLatest(): Automatically cancels any previous pending worker instance if a newer version of the same action is fired.
  • call(): Tells the middleware to invoke an asynchronous function. It blocks execution sequentially until the promise resolves.
  • put(): Dispatches an action back to the Redux Store(the saga version of dispatch).
  • select(): Retrieves a slice of data directly from the current Redux store state.

Code Example: Fetching User Profile Data

import { call, put, takeLatest } from 'redux-saga/effects'
import axios from 'axios';
// 1. Worker Saga: Handles the network call logic
function* fetchUserWorker(action) {
try {
// Pauses here until the Axios HTTP request resolves
const response = yield call(axios.get, `https://example.com{action.payload.id}`);
// Dispatches success action to store with fetched payload
yield put({ type: 'USER_FETCH_SUCCESS', user: response.data })
} catch (error) {
// Dispatches error action if API crashes
yield put({ type: 'USER_FETCH_FAILED', message: error.message })
}
}
// 2. Watches Saga: Watches for actions
export function* userWatcherSaga() {
// Intercepts USER_FETCH_REQUESTED and applies takeLatest strategy
yield takeLatest('USER_FETCH_REQUESTED', fetchUserWorker);
}

Why Use Redux Saga over Redux Thunk ?

  • Declarative testing: Because sagas yield plain objects (Effects) rather than executing promises directly. you can easily unit test them step-by-step without mocking API clients or HTTP networks.
  • Advanced execution controls: Sagas make it straightforward to manage complex async orchestrations like race conditions, task cancellations, throttle limits, and background threading.

How to remove node modules in react project with commands ?

If we are using yarn, We need to use the following commands in the terminal to remove the node modules and cleanup the cache

rm – Rf node_modules

yarn cache clean

yarn install

If we are using npm, We need to use the following commands in the terminal to remove the node modules and cleanup the cache

rm – Rf node_modules

npm cache clean –force

npm install

Breakdown of the Command “rm – Rf node_modules”

  • rm: The command used to remove (delete) files or directories.
  • -r (or -R): Recursive flag. It instructs the terminal to dig inside the folder and delete all nested files and subdirectories.
  • -f: Force flag. It bypasses any confirmation prompts and ignores non-existent files.
  • node_modules: The target folder holding your local Node.js package dependencies.

If we want delete package-lock.json or yarn.lock file then we need to use either

rm -rf node_modules package-lock.json

(or)

rm -rf node_modules yarn.lock

JavaScript Program to find Number of Pairs in an Array

For the array:

const arr = [10, 20, 20, 10, 10, 30, 50, 10, 20];

we need to find how many pairs of matching numbers exist.

Expected Output

3

Explanation:

  • 10 appears 4 times → 2 pairs
  • 20 appears 3 times → 1 pair
  • 30 appears 1 time → 0 pairs
  • 50 appears 1 time → 0 pairs

Total pairs = 2 + 1 = 3


JavaScript Solution

const arr = [10, 20, 20, 10, 10, 30, 50, 10, 20];
function findPairs(numbers) {
const frequency = {};
for (const num of numbers) {
frequency[num] = (frequency[num] || 0) + 1;
}
console.log("Frequency:", frequency);
let pairs = 0;
for (const key in frequency) {
pairs += Math.floor(frequency[key] / 2);
}
return pairs;
}
console.log("Total Pairs:", findPairs(arr));

How to Delete current git branch in Visual Studio Code

If you’re sure the existing branch is no longer required, you can delete it.

To delete current Current branch from Visual Studio Code, First we need to checkout / Switch from that branch to other / main branch.

Example:
git checkout main

For Example, the name of the branch that we need to delete is “test”, we need to use the following command to delete this branch.

git branch -d test

It will delete the branch test

If Git refuses because the branch has unmerged changes, then use the following command.

git branch -D main

⚠️ Warning: The -D option permanently deletes the branch, including commits that are not reachable from another branch. Use it carefully.

CSS accent-color Property

The accent-color CSS property applies the custom accent-color for user-interface controls like  <input type=”checkbox”>, <input type=”radio”>, <input type=”range”> and <progress> .

For Example, default color of checkbox for the following code is as follows

.task-checkbox {
width: 18px;
height: 18px;
min-width: 18px;
cursor: pointer;
}

After applying accent-color as red, it will show as follows

.task-checkbox {
width: 18px;
height: 18px;
min-width: 18px;
cursor: pointer;
accent-color: red;
}

NOTE: By default, browser choose the accent-color. if we need any specific color, we need to give it manually like above.