1. Why we use req,res?
INTRO:-
Hello, and thank you for having me. My name is [Your Name], and I’m a
recent graduate with a strong passion for full stack development. During my
academic journey and personal projects, I’ve gained hands-on experience
with technologies like HTML, CSS, JavaScript, React for the frontend, and
[Link], Express, and MongoDB on the backend.
I’ve built several projects that simulate real-world applications, including
[briefly mention a key project, e.g., 'a job posting platform with dynamic
form handling and real-time features using the MERN stack']. These
experiences helped me understand the full software development lifecycle,
from designing user interfaces to managing databases and deploying
applications.
I’m a quick learner, eager to grow, and excited about the opportunity to
contribute to a professional team where I can apply my skills, learn from
experienced developers, and build impactful solutions.
[Link]
This is a [Link] model class that interacts with a MySQL database to
perform CRUD operations on a tasks table.
1. What is the purpose of this model?
Expected Answer:
This model handles all database operations related to tasks, such as
creating, updating, assigning, and retrieving task data from the MySQL
database.
2. Why did you use mysql2/promise instead of mysql?
I used mysql2/promise because it supports modern async/await syntax,
which makes the code easier to read, avoids callback hell, and improves
error handling.
3. What is connection pooling, and why did you use it?
Connection pooling allows multiple queries to reuse existing database
connections instead of opening a new one every time. It improves
performance and reduces resource usage, especially in a high-load
environment.
9. How would this be different if you used MongoDB?
MongoDB doesn’t use SQL. With Mongoose, I'd use schema-based models
and methods like .create(), .find(), or .updateOne() instead of raw SQL. Also,
there's no need for JOINs; nested or referenced documents can be used.
This TaskModel class is a part of a [Link] backend using MySQL
(via mysql2/promise) to manage task-related operations in a task
management system. Let’s break it down section by section:
✅ Imports and Initialization
const mysql = require('mysql2/promise');
const config = require('../config/database');
mysql2/promise: Promise-based MySQL client to interact with
the database asynchronously.
[Link]: Contains DB connection configuration (host, user,
password, database, etc.).
class TaskModel {
constructor() {
[Link] = [Link]([Link]);
}
A connection pool is created for efficient database access,
reusing connections rather than opening a new one every time.
📌 createTask(taskData)
async createTask(taskData) {
const { title, description, project_id, created_by, assigned_to,
due_date, priority, status } = taskData;
Destructures task details from taskData.
const query = 'INSERT INTO tasks (...) VALUES (?, ?, ..., NOW())';
const [result] = await [Link](query, [...]);
Inserts a new task into the tasks table.
Uses NOW() for automatic timestamping.
return { id: [Link], ...taskData };
Returns the newly created task including the generated id.
📌 getTasksByProjectId(projectId)
const query = 'SELECT t.*, [Link] as assignee_name FROM
tasks t JOIN users u ON t.assigned_to = [Link] WHERE t.project_id
= ?';
Retrieves all tasks under a specific project.
Uses a JOIN to get the username of the assigned user.
📌 updateTask(taskId, taskData)
const query = 'UPDATE tasks SET ... WHERE id = ?';
await [Link](query, [..., taskId]);
Updates task details like title, description, etc. based on the
taskId.
❌ assignTask(taskId, userId) — ⚠️Buggy Implementation
const connection = [Link]();
[Link](query, [userId, taskId]);
[Link]();
This has 2 major issues:
1. [Link]() is asynchronous – it should be
awaited:
2. const connection = await [Link]();
3. execute() is also asynchronous – it should be awaited:
4. await [Link](...);
✔️Fixed version:
async assignTask(taskId, userId) {
const query = 'UPDATE tasks SET assigned_to = ? WHERE id = ?';
const connection = await [Link]();
try {
await [Link](query, [userId, taskId]);
return { success: true };
} finally {
[Link]();
}
}
📌 getTaskById(taskId)
const query = 'SELECT * FROM tasks WHERE id = ?';
const [tasks] = await [Link](query, [taskId]);
return tasks[0] || null;
Fetches task by ID. Returns the task object or null if not found.
✅ Exporting the Model
[Link] = new TaskModel();
Exports an instance of the model class for use in
routes/controllers.
🔁 Summary of Methods
Method Purpose
createTask Insert a new task
getTasksByProjectId Get tasks for a specific project
updateTask Update task details
assignTask Assign a task to a user (⚠️fix required)
getTaskById Retrieve a single task by its ID
Let me know if you'd like help fixing the assignTask() method
properly or expanding this with deleteTask() or filtering features.
[Link]
“This is a UserModel I built as part of a full stack project using
[Link] and MySQL. It handles user-related operations such as
creating a user and finding a user by username or email.
I used the mysql2/promise library to allow async/await, making
the code cleaner and avoiding callback hell. I also used a
connection pool for better performance and resource
management.
The createUser method inserts a new user into the database. I
used parameterized queries to prevent SQL injection, and stored
the created_at timestamp using MySQL’s NOW() function.
The findByUsername and findByEmail methods are used to check
if a user already exists—this is useful for login or signup validation.
They return the first matching user or null if not found.
I also included try/catch blocks for proper error handling and
logging, which I learned is important for debugging and clean API
responses.”
💡 Bonus: What Interviewers Might Ask Based on This
1. What is the purpose of this model?
It abstracts all the logic related to user data and helps keep
controller code clean and organized.
2. How is this secure?
I used parameterized queries (?) to avoid SQL injection and would
typically hash the password before storing it (though not shown
here, I would use bcrypt in production).
3. Why use NOW() in MySQL instead of setting it in JS?
It ensures the timestamp is generated by the database itself,
which is more consistent and avoids time zone issues between
server and DB.
4. What happens if username already exists in the DB?
If there's a UNIQUE constraint on username or email, MySQL will
throw an error. I would catch it in the controller or service layer
and return a user-friendly message like “Username already taken.”
5. How would you write a login function?
I’d use findByUsername or findByEmail to fetch the user, compare
the password using [Link](), and return a token (e.g.,
JWT) if authentication succeeds.
6. How would you test this?
I’d write unit tests using a mocking library like jest or sinon to
simulate DB responses without hitting the actual DB.
[Link]
his is the TaskController class in a [Link] backend project. It
handles incoming HTTP requests related to tasks — like creating,
retrieving, updating, or assigning tasks — and sends responses
back to the client. It interacts with the TaskModel to perform
actual database operations.
✅ Method-by-Method Explanation
1. createTask(req, res)
This method:
Handles POST /tasks requests to create a new task.
Gets data like title, description, project_id, assigned_to, etc. from
[Link].
Uses [Link] as created_by (likely added via auth middleware).
Validates that title and project_id are present.
Sends the data to [Link]() to insert into the database.
Returns a 201 Created response with the new task if successful.
Handles errors with a 500 Internal Server Error if anything goes wrong.
2. getTasksByProject(req, res)
This method:
Handles GET /projects/:projectId/tasks (assumed route).
Extracts projectId from [Link].
Calls [Link]() to fetch all tasks for that project.
Returns a 200 OK response with the list of tasks.
3. updateTask(req, res)
This method:
Handles PUT /tasks/:taskId requests.
Gets the taskId from URL params and update fields from [Link].
Calls [Link](taskId) to ensure the task exists.
If not found, sends a 404 Not Found response.
Otherwise, creates an updatedTaskData object with new or existing
values (fallbacks).
Calls [Link]() to apply the changes.
Returns a 200 OK response with the updated task.
4. assignTask(req, res)
This method:
Handles POST /tasks/:taskId/assign or similar route.
Gets taskId from [Link] and userId from [Link].
Validates that both values are provided.
Calls [Link]() to update the assigned_to field in the DB.
Returns a 200 OK response with a success message and result.
✅ Key Concepts Demonstrated
Express Controller Pattern: Keeps route logic separate from DB logic.
Input Validation: Checks required fields before processing.
Error Handling: Uses try/catch blocks with [Link] logging.
Asynchronous Code: Uses async/await for all DB calls.
RESTful Design: Follows HTTP status codes and response formats.
✅ Bonus: How You Could Explain This in an Interview
“This TaskController class handles all task-related API endpoints. It ensures
that incoming data is validated, interacts with the model to perform
database operations, and returns appropriate HTTP responses. I used
async/await for asynchronous handling and structured each method clearly
to follow RESTful conventions. This helped me understand how a full
backend flow works — from receiving requests to returning responses after
DB operations.”
Why we use req,res?
🔹 req = Request Object
Contains everything sent by the client (browser, frontend,
Postman, etc.).
Common req properties:
[Link] – Data sent in the body (POST/PUT requests)
[Link] – URL parameters (like /tasks/:taskId)
[Link] – Query string parameters (like ?page=2)
[Link] – HTTP headers
[Link] – (Custom) User info if using auth middleware like JWT
🔹 res = Response Object
Used to send a response back to the client.
Common res methods:
[Link]() – Sends a plain response
[Link]() – Sends a JSON object
[Link](code) – Sets the HTTP status code (e.g., 200, 404)
[Link](url) – Redirects to another URL
[Link]
This is a [Link] controller class for managing user-related operations like
registration, profile retrieval, and profile updates. It interacts with a
UserModel for database operations and potentially an AuthService for
authentication (though it's not directly used here).
File Dependencies
UserModel: Responsible for interacting with the database (e.g., finding
and creating users).
AuthService: Presumably handles authentication (e.g., hashing
passwords or verifying tokens), though not used directly in the shown
methods.
1. registerUser(req, res)
This method handles user registration.
Steps:
1. Extract data from [Link]: username, email, password, and fullName.
2. Validation: Ensures username, email, and password are provided. If any
are missing, respond with HTTP 400.
3. Check if user already exists:
o Calls [Link]() and [Link]()
to prevent duplicate registration.
o If found, returns HTTP 409 (Conflict).
4. Create user:
o Constructs a userData object.
o Calls [Link](userData) to save the new user to the
database.
5. Responds with 201 (Created) and returns a success message with the
new user's basic details.
2. getProfile(req, res)
This method retrieves the currently logged-in user's profile.
Steps:
1. Extracts userId from [Link] (typically populated by authentication
middleware).
2. Looks up the user using [Link](userId).
3. If the user does not exist, returns HTTP 404.
4. If found, returns HTTP 200 with the user's basic information.
3. updateProfile(req, res)
Allows the user to update their profile details.
Steps:
1. Extract userId from [Link].
2. Extract new fullName and email from [Link].
3. Updates the user using [Link](userId, { fullName,
email }).
4. Returns HTTP 200 with a success message and updated user info.
Error Handling
All methods use try-catch blocks to catch unexpected errors and respond
with HTTP 500 (Internal Server Error) along with a log to the console.
How to Explain in an Interview
You can say:
"This controller manages user-related actions. It validates input, checks for
existing users, and communicates with the UserModel to interact with the
database. I’ve ensured proper error handling and appropriate HTTP status
codes for different scenarios. The code is modular and keeps the controller
logic clean by offloading database logic to a separate model layer."
🔹 Basic Functionality Questions
1. How does your registerUser method handle duplicate users?
o Expected Answer: "It checks if the username or email already
exists using [Link] and findByEmail, and
returns a 409 Conflict if a match is found."
2. Why do you validate input fields manually in the controller? Would you
improve this?
o Expected Answer: "For now, it's a simple check, but in production
I’d use a validation library like Joi or express-validator to handle
validation more robustly and maintainably."
🔹 Security Questions
3. Are passwords stored securely in this implementation?
o Expected Answer: "Not yet. Right now, passwords are stored as
plain text, which is insecure. I would hash them using bcrypt
during registration and compare hashed values during login."
4. How do you prevent mass assignment vulnerabilities when creating or
updating users?
o Expected Answer: "By only picking specific allowed fields
(username, email, password, fullName) instead of spreading all
[Link] values into the user model."
🔹 Design & Architecture
5. Why did you separate logic into a UserModel and UserController?
o Expected Answer: "It follows the MVC pattern — controllers
handle request/response logic, while models handle data
persistence and database logic. This separation improves
maintainability and scalability."
6. How would you handle sending a welcome email after registration?
o Expected Answer: "I'd integrate an email service like SendGrid or
Nodemailer inside the registration flow, ideally via a separate
service layer or message queue to avoid blocking the response."
🔹 Scalability & Error Handling
7. How would you make error messages more useful for debugging
without exposing sensitive information?
o Expected Answer: "I’d log the full error details internally using a
logger (like winston), but return a generic message to the client
like 'Something went wrong'."
8. What happens if two users try to register with the same email at the
same time?
o Expected Answer: "If this is not handled atomically in the
database, both could pass the duplicate check. To prevent this, I
would enforce a unique index on the email/username fields in the
database."
🔹 Advanced Questions
9. How would you allow users to update only specific fields (e.g., just
fullName)?
o Expected Answer: "In updateProfile, I’d dynamically build the
update object based on what's provided in [Link], filtering out
disallowed fields."
[Link] would you write unit tests for these controller methods?
o Expected Answer: "I'd use a testing framework like Jest or Mocha,
mock the UserModel methods using tools like [Link] or sinon,
and test expected responses for valid and invalid input cases.
[Link]
1. login(req, res)
Purpose: Authenticates a user and returns a JWT.
Steps:
1. Extract credentials from request body:
js
CopyEdit
const { username, password } = [Link];
2. Check for missing fields:
Returns a 400 Bad Request if either username or password is
missing.
3. Fetch user from the database:
js
CopyEdit
const user = await [Link](username);
4. If user doesn't exist: return 401 Unauthorized.
5. Validate password (Note: currently insecure!):
js
CopyEdit
const isPasswordValid = password === [Link];
⚠️Plain text comparison – in production, you should use
[Link]() to securely hash and compare passwords.
6. If password is invalid: return 401 Unauthorized.
7. Generate JWT:
js
CopyEdit
const token = [Link](
{ id: [Link], username: [Link] },
[Link],
{ expiresIn: '24h' }
);
8. Return response:
o 200 OK
o Basic user info (excluding password)
o JWT token
### 2. validateToken(req, res)
Purpose: Verifies the authenticity of a JWT.
Steps:
1. Extract token from Authorization header:
js
CopyEdit
const token = [Link]?.split(' ')[1];
2. If no token: return 401 Unauthorized.
3. Verify the token:
js
CopyEdit
[Link](token, [Link], ...)
If it's invalid or expired, return 401 Unauthorized.
4. If valid: return 200 OK with decoded user info.
### 3. logout(req, res)
Purpose: Logs the user out.
Behavior:
Since JWTs are stateless, the backend cannot "invalidate" a
token unless using a token blacklist or short expiry.
This method just sends a message:
js
CopyEdit
[Link](200).json({ message: 'Logout successful' });
🔹 Basic Understanding
1. Can you explain how the login flow works?
Expected Answer: "The login method checks for missing fields,
finds the user by username, compares the hashed password using
[Link], and if valid, signs and returns a JWT with user
info."
2. Why do you use JWTs instead of sessions?
Expected Answer: "JWTs are stateless, so the server doesn’t need
to store session data. They work well in distributed systems like
microservices or SPAs. However, they require proper handling of
expiry, refresh tokens, and security against token theft."
🔐 Security-Related Questions
3. How do you secure passwords?
Expected Answer: "Passwords are hashed using bcrypt before
being stored in the database. During login, we use [Link]
to check the plaintext password against the hash."
4. Why shouldn't we store passwords as plain text?
Expected Answer: "If the database is breached, all user accounts
would be compromised. Hashing makes it computationally
infeasible to reverse-engineer the original password."
5. How would you implement logout with JWTs, since they are
stateless?
Expected Answer:
"Since JWTs are stored client-side, logout is typically handled by
the client deleting the token (from memory or cookies)."
"To improve security, we could use short-lived access tokens
with long-lived refresh tokens and revoke them using a token
blacklist."
6. What are some ways to prevent brute-force attacks on the
login endpoint?
Expected Answer:
Implement rate limiting or IP throttling (e.g., express-rate-limit).
Add account lockout after several failed attempts.
Use CAPTCHA for bot detection.
⚙️Token Handling & Verification
7. What data do you include in a JWT payload?
Expected Answer: "Only minimal, non-sensitive information like
user ID and username. Avoid storing passwords or roles unless
absolutely necessary."
8. What happens if someone tampers with a JWT token?
Expected Answer: "The server uses [Link]() with the secret key
to check the token’s integrity. If it’s modified, the signature won’t
match and it will be rejected."
🧪 Testing & Error Handling
9. How would you test the login and token validation logic?
Expected Answer:
"I would write unit tests using Jest or Mocha."
"Mock the database calls (UserModel) and test both success
and failure cases: invalid credentials, missing fields, invalid
tokens, etc."
🔄 Advanced / Design-Level
10. How would you improve the login system for a production
environment?
Expected Answer:
Use HTTPS to encrypt tokens in transit.
Store tokens in HttpOnly cookies to prevent XSS.
Use refresh tokens and token rotation.
Implement email verification, multi-factor authentication
(MFA), and password reset workflows
“We moved the authentication logic into a separate service
(AuthService) to improve modularity and separation of concerns.
The controller focuses only on request/response handling, while
the service encapsulates logic like verifying passwords and
generating tokens. This makes the code easier to maintain and
test.
[Link]
✅ What does [Link] do?
This file encapsulates the authentication logic into a service class,
separating business logic from the controller layer.
It includes:
1. authenticateUser() → to verify user credentials and return a
JWT.
2. generateToken() → to sign a JWT.
3. verifyToken() → to verify a JWT’s authenticity.
🔍 Explanation: Line by Line
authenticateUser(username, password)
Fetch user by username:
js
CopyEdit
const user = await [Link](username);
Check if user exists, else return:
js
CopyEdit
return { success: false, message: 'User not found' };
Compare passwords (currently insecure plain comparison):
js
CopyEdit
const isPasswordValid = password === [Link];
If password is invalid, return:
js
CopyEdit
return { success: false, message: 'Invalid password' };
If valid, generate a JWT and return user info:
js
CopyEdit
const token = [Link](user);
generateToken(user)
Creates and signs a JWT with:
[Link] and [Link]
Secret from config
Expiry: 24 hours
js
CopyEdit
[Link]({ id: [Link], username: [Link] }, [Link],
{ expiresIn: '24h' })
verifyToken(token)
Verifies a JWT:
If valid: return decoded data
If invalid or expired: return valid: false
js
CopyEdit
[Link](token, [Link])
[Link]
TaskService is a service class that handles the business logic related
to tasks — assigning them, retrieving them, and updating their
status.
It separates logic from the controller layer, making it more reusable,
testable, and maintainable.
🔍 Function-by-Function Breakdown
1. assignTaskToUser(taskId, userId)
Fetches a task by its ID using:
js
CopyEdit
const task = await [Link](taskId);
If not found, returns:
js
CopyEdit
{ success: false, message: 'Task not found' }
If found, assigns it using:
js
CopyEdit
await [Link](taskId, userId);
Returns a success message.
2. getTasksForUser(userId)
Retrieves all tasks assigned to a specific user via:
js
CopyEdit
const tasks = await [Link](userId);
Returns the list of tasks in a structured response:
js
CopyEdit
{ success: true, tasks }
3. updateTaskStatus(taskId, status)
First checks if the task exists:
js
CopyEdit
const task = await [Link](taskId);
If not, returns:
js
CopyEdit
{ success: false, message: 'Task not found' }
If it exists, updates its status:
js
CopyEdit
const updatedTask = await [Link](taskId, { status });
Returns the updated task object.
🧠 What You Can Say in an Interview
“TaskService follows the Service Layer pattern, separating task
management logic from controller routes. This makes our app
cleaner and supports testing and reuse. Each method handles a
specific business action — assigning, fetching, or updating tasks —
and interacts with the TaskModel, which likely contains the database
layer.”
🔹 General Design Questions
1. What is the purpose of the service layer?
Expected answer: "The service layer encapsulates business logic and
separates it from HTTP logic (controller). It makes the code modular,
testable, and easier to maintain."
2. Why not put all this logic directly in the controller?
Expected answer: "Placing logic in the controller makes it bulky and
harder to test. Using a service keeps responsibilities separate and lets
us reuse business logic across controllers or even jobs/queues."
🔐 Validation & Error Handling
3. What happens if taskId or userId is invalid or undefined?
Follow-up: "Shouldn't you validate input before hitting the
database?"
4. How would you improve error handling in this service?
Expected answer: "Use a centralized logging system like Winston,
return error codes consistently, and maybe throw custom errors
instead of returning generic objects."
🔄 Function-Specific Questions
5. In assignTaskToUser, what if the task is already assigned?
Follow-up: "Should you prevent duplicate assignments or notify the
client?"
6. What’s a potential issue with getTasksForUser if there are
thousands of tasks?
Expected answer: "We should use pagination to avoid performance
and memory issues."
7. In updateTaskStatus, how would you handle invalid status
values?
Expected answer: "I’d define allowed status values (pending, in
progress, done, etc.) and validate input against them."
🧪 Testing & Scalability
8. How would you write unit tests for these methods?
Expected answer: "I'd mock TaskModel methods using Jest or Sinon,
and test each service method for success and failure paths."
9. What if two users try to update the same task status at the same
time?
Expected answer: "This could lead to race conditions. We might need
optimistic locking or versioning in the database."
10. What if the task assignment fails halfway through a multi-step
operation?
Expected answer: "We’d use transactions (e.g., MongoDB sessions or
SQL transactions) to ensure atomicity."
🧠 Advanced Thinking
11. How would you redesign this service to support task deadlines,
priorities, or comments?
Expected answer: "I’d expand the TaskModel and add methods like
updateTaskPriority, addTaskComment, and possibly break this into
multiple smaller services if needed."
12. How would you handle notifications (e.g., send email when a
task is assigned)?
Expected answer: "I'd use an event-driven approach or a message
queue like RabbitMQ or Bull to handle side effects like notifications
asynchronously."
FRONTEND
[Link]
The TaskItem component is a reusable UI block that displays
details of a single task like its title, description, due date, assignee,
status, and priority.
Key Props:
It receives a task object as a prop which contains:
o id, title, description, due_date, priority, status,
assignee_name
Functionality:
formatDate: Converts the due_date to a user-friendly format
using toLocaleDateString().
getStatusClass: Maps the status (e.g., completed, in-progress,
pending) to corresponding CSS class names for styling.
getPriorityClass: Similarly maps priority to appropriate CSS
classes.
SX Output:
Displays:
o The task title.
o Task description or fallback (No description provided).
o Due date, assignee, and priority, each styled based on its
value.
o Status shown with dynamic styling using class names.
Why it’s well-designed:
It's clean, modular, and focuses only on presentation.
It handles missing data gracefully with default fallbacks.
[Link]
🔹 [Link] – Custom Hook to Fetch and Cache Project
Tasks
Instead of writing the same data-fetching logic inside multiple
components, we use a custom hook (useTaskCache) to keep our
code DRY (Don't Repeat Yourself) and make it reusable and
testable.
Effect Hook (useEffect):
Runs every time projectId changes.
Triggers the fetchTasks() function to fetch task data from the
backend.
API Call:
Uses [Link]() to hit the endpoint /tasks/project/${projectId}.
On success: stores tasks in state and clears any errors.
On failure: catches the error and stores an error message.
finally: sets loading to false regardless of success or failure.
Return Value:
Returns an object { tasks, loading, error } that can be consumed
by any component (like TaskList) to handle the UI accordingly.
1. What is a custom hook in React, and why would you use one?
Answer:
A custom hook is a reusable function in React that starts with use
and can use other React hooks internally. I used useTaskCache to
abstract the logic for fetching tasks, handling loading states, and
managing errors based on projectId. This improves separation of
concerns, keeps UI components clean, and encourages reuse of
logic across multiple components.
2. How is useEffect used in your useTaskCache hook?
Answer:
I use useEffect to trigger the fetchTasks function when the
component mounts or whenever the projectId changes. This
ensures that every time the projectId changes, the latest tasks are
fetched from the API. It simulates lifecycle behavior in function
components, like componentDidMount and
componentDidUpdate.
3. Why is projectId in the dependency array of useEffect?
Answer:
It ensures the effect re-runs whenever the projectId changes.
Without it, the hook would not fetch tasks for the newly selected
project, resulting in outdated or incorrect data being shown.
4. What would happen if you didn’t include projectId in the
dependency array?
Answer:
The useEffect would run only once on mount, and not when
projectId changes. As a result, tasks would not update when
switching between different projects — leading to stale or
incorrect task lists being displayed.
5. What is the purpose of the finally block in the async function?
Answer:
The finally block ensures that setLoading(false) is executed
regardless of whether the API call succeeds or fails. Without it, the
loading spinner might stay indefinitely if an error occurs, hurting
the user experience.
6. Can you add caching to this hook to avoid re-fetching the same
data? How?
Answer:
Yes, I could use a useRef to store a cache object keyed by
projectId. Before making an API call, I’d check if the data exists in
the cache. If it does, I’d use that instead. Alternatively, for shared
cache across components, I could use context or integrate a library
like React Query that handles caching out of the box.
Example using useRef:
js
CopyEdit
const cache = useRef({});
if ([Link][projectId]) {
setTasks([Link][projectId]);
setLoading(false);
return;
}
7. How would you modify this hook to support pagination or
filtering?
Answer:
I would extend the hook to accept additional parameters like page,
limit, or filterStatus. These would be added to the API call and to
the dependency array. For example:
js
CopyEdit
const useTaskCache = (projectId, page = 1, filterStatus = '') => { ... };
This makes the hook more flexible and scalable for real-world use
cases.
✅ Error Handling & UX
8. How does your hook handle API errors? What would you
improve?
Answer:
It catches errors in a try-catch block and updates the error state to
show a user-friendly message. One improvement would be to
differentiate error types — for example, handling 404 vs 401
differently — and to implement retry logic or show a toast
notification using a library like react-toastify.
9. If the backend returns a 401 error, how could you show a login
prompt from the hook?
Answer:
In the catch block, I would inspect the error response. If it's a 401,
I could trigger a global login flow — either by calling a
redirectToLogin() function from context or dispatching an action
using Redux to open a login modal.
js
CopyEdit
if ([Link]?.status === 401) {
// trigger logout or redirect
}
✅ Fullstack / API Integration
10. What does your /tasks/project/:projectId API endpoint
return?
Answer:
It returns a JSON response containing a list of tasks associated
with the given projectId. A typical response might look like:
json
CopyEdit
{
"tasks": [
{ "id": 1, "title": "Bug Fix", "status": "pending", ... }
]
}
My hook extracts the tasks array from [Link] and
updates the state accordingly.
11. How would you secure this API endpoint in a real-world app?
Answer:
I’d secure it using authentication (e.g. JWT token in headers) and
server-side authorization checks. The backend would verify the
user’s identity and ensure they have access to the given projectId.
If not authorized, it would return a 403 Forbidden status.
js
CopyEdit
Authorization: Bearer <JWT_TOKEN>
12. What would you do if the backend API is slow? How can you
improve perceived performance?
Answer:
I’d implement the following:
Skeleton loaders or spinners to show progress.
Caching to avoid repeated calls.
Debounce filter inputs or search.
Background revalidation (e.g., with React Query).
Optionally, optimistic updates if the user initiates a task edit or
creation.
🔹 9. What improvements would you make for production usage?
Answer:
Add retry logic on failure.
Use a loading skeleton or debounce.
Add support for filtering or pagination.
Implement caching to reduce redundant API calls.
Replace with a data-fetching library like react-query for built-in
caching, deduplication, and background refetching.
[Link] questions
Great! Based on your [Link] component, here’s a tailored list of interview questions
along with detailed answers that assess your front-end skills in React, component design,
conditional rendering, CSS integration, and best practices.
✅ Interview Questions & Answers: [Link]
1. What does the TaskItem component do?
Answer:
TaskItem is a presentational React component that displays task details like title, description,
due date, priority, status, and assignee. It uses conditional rendering to handle missing fields
and applies dynamic CSS classes based on status and priority for visual distinction.
2. Why do you use formatDate in this component?
Answer:
The formatDate function converts the raw due_date string into a human-readable format
using toLocaleDateString(). If the date is missing, it returns 'No due date', ensuring the
UI doesn’t break and remains user-friendly.
3. How do getStatusClass and getPriorityClass work, and why are they
useful?
Answer:
These helper functions return specific class names (status-completed, priority-high,
etc.) based on the task’s status or priority. They help conditionally style elements using
CSS, improving visual feedback (e.g., coloring completed tasks green).
4. How does TaskItem handle missing or undefined data like description or
assignee_name?
Answer:
The component uses short-circuiting (||) to provide fallback values:
description || 'No description provided'
assignee_name || 'Unassigned'
This prevents rendering issues and maintains a smooth user experience.
5. Why are CSS class names dynamically constructed using template literals?
Answer:
Template literals (${}) are used to combine base class names with conditional classes from
helper functions. This makes the code cleaner and more scalable for future UI changes.
Example:
<div className={`task-status ${getStatusClass(status)}`}></div>
6. What is the benefit of separating logic like formatting and class mapping
into functions?
Answer:
It improves readability, reusability, and testability. Instead of cluttering JSX with
conditional logic, the functions encapsulate logic in one place. This also follows the principle
of separation of concerns.
7. Could this component be written as a memoized component? When would
that help?
Answer:
Yes, if TaskItem receives the same props frequently (e.g., in a list), wrapping it with
[Link] could prevent unnecessary re-renders, improving performance. It’s especially
helpful when rendering large task lists.
export default [Link](TaskItem);
8. How would you improve accessibility (a11y) in this component?
Answer:
Use semantic HTML elements like <article> or <section> instead of <div>.
Add ARIA labels or roles to indicate task status or priority.
Use color plus text icons (not just color) for status indicators for colorblind
accessibility.
9. How would you test this component?
Answer:
Using a tool like React Testing Library, I'd write unit tests to:
Verify it renders the correct title, description, and due date.
Check fallback values render correctly when fields are missing.
Ensure the correct CSS class is applied for different status and priority values.
10. How would you make this component reusable in other projects?
Answer:
I’d extract the core logic and CSS into a shared UI library. I’d also make it more configurable
via props or context (e.g., allowing custom class mappings or tooltips), and document its
usage.
Bonus Questions:
11. What would you do if the priority field came as a number (1 = high, 2 = medium...)
instead of a string?
Answer:
I’d add a mapping function like:
const priorityMap = { 1: 'high', 2: 'medium', 3: 'low' };
const getPriorityClass = (priority) => {
const level = priorityMap[priority] || 'none';
...
};
12. How would you animate a task’s appearance on the list (e.g., when it's added)?
Answer:
I’d use CSS transitions or a library like framer-motion to animate the entry, fade-in, or
expansion of a TaskItem when added to the list. This improves the visual flow of UI
changes.
Let me know if you’d like a task summary component, test case examples, or a design
improvement plan for this UI!
[Link]
This component, TaskList, is responsible for displaying a list of
tasks for a given project. It fetches the data using a custom hook
(useTaskCache), allows filtering tasks by their status (like pending
or completed), and renders each task using a child component
called TaskItem.
🔹 Walk Through Key Parts with Purpose
1. Fetching Tasks
“I'm using a custom hook, useTaskCache(projectId), which
abstracts the API call logic. It returns tasks, a loading flag, and any
error. This keeps the data-fetching logic separate from the UI,
which improves code reuse and maintainability.”
2. Handling Loading and Error States
“If the tasks are still loading, the component shows a loading
message. If there's an error, like a network failure, it displays the
error to the user. This helps with user experience and clarity.”
3. Filtering Tasks by Status
“I use a useState hook to manage the current filter, and a filter
function on the tasks array to only show relevant tasks based on
the selected status. The filter buttons let the user toggle between
views like All, Pending, In Progress, and Completed.”
4. Rendering Tasks
“If no tasks match the filter, I display a fallback message saying ‘No
tasks found’. Otherwise, I map through the filtered tasks and
render each one using the TaskItem component, which keeps the
UI modular and readable.”
5. Styling and Active Button State
“The currently selected filter is visually highlighted using
conditional classNames — for example, className={filter ===
'all' ? 'active' : ''} — which helps users understand which view
they’re in.”
🔹 Optional Improvements You Can Offer
“In the future, I could enhance this by adding search, pagination,
or even drag-and-drop to reorder tasks. Also, depending on the
project scale, task filters and state could be lifted into a global
state like Redux or Zustand.”
✅ Wrap Up with What This Shows
“Overall, this component demonstrates how I separate concerns
— fetching logic via a hook, UI logic in the component, and styling
in CSS. It also shows how I handle dynamic UI updates, conditional
rendering, and maintain accessibility and UX.”
"Can you walk me through your TaskList component and how it
works?"
🧑💻 You (Ideal Answer):
"Sure! The TaskList component is designed to display all tasks
associated with a specific project. It takes in a projectId prop,
which I use to fetch tasks from the backend through a custom
hook called useTaskCache."
"This hook handles all the data-fetching logic — it returns the list
of tasks, a loading state, and an error if something goes wrong.
This helps keep the component itself focused on rendering logic
and improves reusability across the app."
"While the data is being fetched, I show a loading message. If
there's an error, I display it to the user — so the user always knows
what's going on."
"Once the tasks are available, I allow filtering them based on their
status — like pending, in-progress, or completed. I use a useState
hook to track the current filter, and then filter the task array
accordingly before rendering."
"Each task is rendered through a TaskItem component to keep
things modular. If there are no tasks that match the selected filter,
I show a 'No tasks found' message instead."
"There are also buttons at the top to toggle between filters. Each
button highlights itself when active — this is done using
conditional class names — which gives users visual feedback on
their current selection."
"If I were to extend this, I’d consider adding search, sorting, or
pagination. And if the app grew in complexity, I might lift task
filtering and state into a global state manager like Redux or
Zustand."
"So overall, this component demonstrates how I separate data
logic from UI, handle all edge cases like errors and empty states,
and keep the user experience smooth and clear."
1. How does the useState hook work in your TaskList
component?
Answer:
I use the useState hook to create a piece of state called filter,
which holds the current filter value like 'all', 'pending', etc. This
state controls which tasks are shown. When a user clicks a filter
button, I call setFilter to update this state, causing React to re-
render the component with the filtered task list. This lets me
manage dynamic UI changes smoothly and efficiently.
2. Why do you use a custom hook useTaskCache instead of
fetching tasks directly inside TaskList?
Answer:
The custom hook useTaskCache abstracts the logic for fetching
tasks, handling loading and error states, and managing side
effects. This keeps the TaskList component clean and focused on
rendering and filtering tasks. It also makes the fetching logic
reusable across other components if needed, improving
maintainability and separation of concerns.
3. How does conditional rendering work in your component?
Answer:
I use conditional rendering to handle different UI states. For
example, if the data is loading, I render a loading message. If
there’s an error, I display the error. If there are no tasks matching
the filter, I show a ‘No tasks found’ message. Otherwise, I render
the list of filtered tasks. This ensures the user always sees relevant
feedback based on the current app state.
4. What is the purpose of the filter state and how do you use it to
filter tasks?
Answer:
The filter state stores the currently selected filter option. I use it to
filter the tasks array by matching the task’s status property. For
example, if filter is 'completed', only tasks with status ===
'completed' are shown. This filtering is done using the JavaScript
[Link]() method before rendering the tasks.
5. What happens if projectId changes? How does your
component respond?
Answer:
When projectId changes, the useTaskCache hook detects the
change because it includes projectId in its useEffect dependency
array. It then re-fetches the tasks for the new project and updates
the tasks state. This causes TaskList to re-render with the new data
automatically, ensuring the UI always reflects the correct project
tasks.
6. How do you handle loading and error states in your
component?
Answer:
I check the loading and error flags returned from useTaskCache.
While loading is true, I render a loading message so the user
knows data is being fetched. If error is not null, I display the error
message to inform the user something went wrong. This provides
good user feedback and improves the user experience.
7. What is the significance of the key prop in [Link]()?
Answer:
React requires a unique key prop for each element in a list to
efficiently identify which items have changed, been added, or
removed. In my component, I use [Link] as the key because it
uniquely identifies each task. This helps React minimize DOM
updates, improving rendering performance.
8. How do you update the filter when a user clicks on a filter
button?
Answer:
Each filter button has an onClick handler that calls setFilter with
the corresponding filter value. For example, clicking the “Pending”
button sets the filter state to 'pending'. This updates the state and
triggers a re-render, showing only tasks that match the new filter.
9. How would you improve performance if the task list becomes
very large?
Answer:
To handle large lists, I’d consider using React’s useMemo hook to
memoize the filtered task list so the filter operation only runs
when the tasks or filter state change. I could also implement
pagination to load tasks in smaller chunks, or use virtualization
libraries like react-window to render only visible items and reduce
DOM load.
10. Why do you use buttons for filters instead of a dropdown or
other UI elements?
Answer:
Buttons provide immediate, visible filter options, making it easy
for users to understand and switch between views quickly. This
improves usability and accessibility, as the active filter is clearly
indicated. Dropdowns could hide options and require extra clicks,
which might slow down the user experience for frequent filter
changes.
[Link]
Explanation of the axios instance with interceptor:
1. Creating a custom axios instance:
js
CopyEdit
const api = [Link]({
baseURL: [Link].REACT_APP_API_URL || 'http:'
});
You create a reusable axios instance named api with a base
URL.
[Link].REACT_APP_API_URL is an environment variable
storing your API endpoint.
If the env variable is missing, it falls back to 'http:' (which looks
incomplete — you might want to fix that).
Using a custom instance helps centralize API config (base URL,
headers, etc.) across your app.
2. Adding a request interceptor:
js
CopyEdit
[Link](
(config) => {
const token = [Link]('token');
if (token) {
[Link]['Authorization'] = `Bearer ${token}`;
}
return config;
},
(error) => {
return [Link](error);
}
);
Before any request is sent, this interceptor runs.
It reads a token (usually a JWT) from localStorage.
If a token exists, it adds an Authorization header with Bearer
<token>.
This allows protected API endpoints to authenticate the
request.
If there's an error preparing the request, it rejects the promise.
3. Exporting the configured axios instance:
js
CopyEdit
export default api;
Other modules import this api to make HTTP requests.
Ensures consistent headers and base URL across all requests.
Possible Interview Questions & Answers:
1. What is the purpose of creating a custom axios instance?
Answer:
It centralizes configuration like the base URL and headers, so you
don’t repeat the same setup in multiple files. It also allows you to
add interceptors for all requests or responses globally.
2. How does the request interceptor work, and why is it useful?
Answer:
The interceptor runs before every HTTP request. It can modify the
request config, such as adding an Authorization header if a token
exists. This is useful for automatically attaching auth tokens
without manually adding headers to every request.
3. Why do you get the token from localStorage inside the
interceptor rather than once when the instance is created?
Answer:
Because the token can change (e.g., user logs in or out), fetching it
fresh from localStorage before each request ensures the latest
token is used.
4. What happens if no token is found in localStorage?
Answer:
The request proceeds without an Authorization header. This might
be fine for public endpoints but will likely cause authentication
failure for protected endpoints.
5. What would you do to handle expired or invalid tokens with
this axios setup?
Answer:
I would add a response interceptor to catch 401 Unauthorized
errors. When detected, I could redirect the user to login or refresh
the token using a refresh token workflow.
6. What could be a potential issue with the baseURL in this code?
Answer:
The fallback 'http:' is incomplete and invalid. It should be a valid
URL like '[Link] or just throw an error to ensure
the base URL is properly set.
7. How can you handle API errors globally using axios
interceptors?
Answer:
You can add a response interceptor that checks for errors and
handles them centrally, e.g., showing notifications, logging out the
user on 401, or retrying requests.
8. Why do you return [Link](error) in the error handler
of the interceptor?
Answer:
To propagate the error so it can be caught in the component or
wherever the API call is made, allowing proper error handling
downstream.
9. How would you test this API service layer?
Answer:
By mocking axios in tests, verifying that the Authorization header
is added correctly, and checking how errors are handled in
interceptors.
he services folder is a common convention to organize code that
interacts with external systems, like APIs or backend services.
It separates data fetching logic from UI components and other
business logic, keeping the project structure clean and
maintainable.
This way, all API calls and configurations (like the axios instance)
are centralized in one place, making it easier to update or reuse
across the app.
React Questions
Absolutely! Here's a more interview-friendly version of selected
answers written in 2–3 detailed lines each, demonstrating clear
understanding:
3. Features of React
React is a component-based JavaScript library that uses a Virtual
DOM to optimize rendering. It supports unidirectional data flow,
JSX for writing UI, and powerful hooks for managing state and side
effects.
4. What is JSX?
JSX stands for JavaScript XML and allows us to write HTML-like
code in JavaScript. It makes code more readable and helps define
component structures intuitively, though it compiles to
[Link]() behind the scenes.
5. What is DOM?
DOM (Document Object Model) represents the structure of a
webpage as a tree of nodes. JavaScript uses it to dynamically
update content, structure, and style in the browser.
6. What is Virtual DOM?
Virtual DOM is an in-memory representation of the real DOM.
React uses it to detect changes efficiently, then updates only the
parts of the real DOM that changed, improving performance.
7. Component Lifecycle (Class Component)
React class components go through Mounting, Updating, and
Unmounting phases. Methods like componentDidMount,
shouldComponentUpdate, and componentWillUnmount let us
hook into these phases to manage logic like fetching data or
cleanup.
8. What are Fragments in React?
Fragments let you group multiple child elements without adding
extra DOM nodes. Useful when a component must return multiple
elements but React requires a single root.
9. What are Props in React?
Props (short for properties) are read-only values passed from
parent to child components. They help make components dynamic
and reusable by externalizing data and configuration.
10. What are Synthetic Events in React?
Synthetic events wrap the browser’s native events to ensure
consistent behavior across all browsers. They follow the W3C spec
and have the same interface regardless of the browser.
11. [Link] vs [Link]
[Link] defines the project dependencies and scripts.
[Link] records the exact version of every installed
package, ensuring reproducible builds.
12. Client-side vs Server-side Rendering
In client-side rendering, the browser renders UI after JavaScript
loads. Server-side rendering pre-renders HTML on the server,
leading to faster initial load time and better SEO.
13. What is State in React?
State is a mutable object managed within a component. It holds
dynamic data and determines what gets rendered based on user
interactions or data changes.
15. State vs Props
Props are external and immutable, passed from parent to child.
State is internal to a component and can be changed using
useState or [Link].
16. What is Props Drilling?
Props drilling happens when data is passed through multiple layers
of components unnecessarily just to reach a deeply nested child,
making code harder to manage.
17. Disadvantages of Prop Drilling and Solutions
It clutters intermediate components with unrelated props. We can
solve it using Context API, Redux, or global state managers to
share data efficiently.
18. What are Pure Components?
A PureComponent does a shallow comparison of props and state
to prevent unnecessary re-renders. It boosts performance in
components with the same input resulting in the same output.
19. What are Refs in React?
Refs provide a way to access DOM elements or component
instances directly. They’re useful for tasks like focusing input fields
or reading form values without re-rendering.
20. What is Forward Ref?
Forward Refs allow parent components to access a child’s DOM
node or ref value. It’s used when building reusable UI components
that need to expose internal refs.
I can continue with the rest in the same format. Would you like me
to complete all 53 with this 2–3 line detailed style, or prioritize
specific ones first (e.g., hooks, context, lifecycle, performance,
etc.)?
Great! Here's the continued list of React interview questions (21–
40) answered in 2–3 detailed lines each:
21. What are Error Boundaries?
Error boundaries are React components that catch JavaScript
errors in their child component tree and display a fallback UI. They
prevent the entire app from crashing and log the error gracefully.
22. What are Higher-Order Components (HOC)?
An HOC is a function that takes a component and returns a new
component with enhanced behavior. It's commonly used for
reusing logic like authentication, theming, or logging.
23. Controlled vs Uncontrolled Components
Controlled components rely on React state for input values,
offering better control over form data. Uncontrolled components
use refs to access DOM values directly, suitable for simpler use
cases.
24. What is useCallback?
useCallback memoizes a function so it only re-creates when
dependencies change. It’s useful for preventing unnecessary re-
renders when passing callbacks to child components.
25. useMemo vs useCallback
Both are used for performance optimization. useMemo memoizes
a value, while useCallback memoizes a function. Use useMemo
when you need to cache computed results.
26. What are Keys in React?
Keys are unique identifiers used in lists to help React track items
and optimize rendering. Without keys, React may re-render
incorrectly or inefficiently.
27. What is Lazy Loading in React?
Lazy loading defers loading components until they are needed.
React's [Link]() with Suspense helps split code and load
components only when they’re rendered, improving performance.
28. What is Suspense in React?
Suspense is a component used to show fallback content (like a
loader) while a lazy-loaded component or data fetch is in progress.
It works with both [Link] and data fetching libraries.
29. What are Custom Hooks?
Custom hooks are reusable functions that use React hooks
internally. They allow you to share logic (like form handling or
fetching data) between components without duplicating code.
30. What is useReducer Hook?
useReducer is a React hook used for managing complex state logic.
It takes a reducer function and an initial state, returning the
current state and a dispatch function—similar to Redux.
31. What are Portals in React?
Portals allow you to render children into a DOM node outside the
parent component’s DOM hierarchy. Useful for modals, tooltips,
and overlays that need to escape container overflow.
32. What is Context in React?
Context is used to pass data through the component tree without
prop drilling. It’s ideal for global values like themes, auth, or locale
settings.
33. Context API Usage Example
// [Link]
const ThemeContext = [Link]();
function App() {
return (
<[Link] value="dark">
<Child />
</[Link]>
);
}
function Child() {
const theme = [Link](ThemeContext);
return <div>Theme is {theme}</div>;
}
34. Why use callback in setState()?
React's setState is asynchronous, so to access the updated state
reliably, you can use a callback function after the state update
finishes, especially for dependent logic.
35. Custom Hook for Counter (Increment/Decrement)
function useCounter(initial = 0) {
const [count, setCount] = [Link](initial);
const increment = () => setCount(c => c + 1);
const decrement = () => setCount(c => c - 1);
return { count, increment, decrement };
}
36. Class Lifecycle Methods Replaced by useEffect
componentDidMount, componentDidUpdate, and
componentWillUnmount are all replaced by the useEffect hook in
functional components using the dependency array.
37. What is Strict Mode in React?
<[Link]> is a wrapper that activates extra checks and
warnings during development. It helps detect unsafe lifecycles,
legacy API usage, and potential issues.
38. Ways to Pass Data from Child to Parent
You can pass a callback function from parent to child and invoke it
from the child with the data. Other ways include using context,
refs, or external state managers like Redux.
39. Send Data from Child to Parent using Callback
function Parent() {
const handleData = (data) => [Link](data);
return <Child onSend={handleData} />;
}
function Child({ onSend }) {
return <button onClick={() => onSend("Hello from
child")}>Send</button>;
}
40. Send Data from Child to Parent using useRef
function Parent() {
const childRef = [Link]();
const handleClick = () => {
[Link]([Link]);
};
return (
<>
<Child ref={childRef} />
<button onClick={handleClick}>Get Data</button>
</>
);
}
const Child = [Link]((props, ref) => {
return <input ref={ref} />;
});
Would you like me to complete 41–53 now in the same style?
Perfect! Here's the final set of React interview answers (41–53)
written in 2–3 detailed lines each:
41. How do you optimize your React application?
Use [Link], useCallback, and useMemo to prevent
unnecessary re-renders. Also, implement code splitting with
[Link], avoid anonymous functions in JSX, and keep state
minimal and localized.
42. How would you consume a RESTful JSON API in React?
useEffect(() => {
fetch("[Link]
.then(res => [Link]())
.then(data => setData(data));
}, []);
Use fetch or libraries like Axios inside useEffect to call APIs and
store data in state.
43. Different Design Patterns in React
Container-Presenter Pattern: Separates logic and UI.
HOC Pattern: Wraps components for code reuse.
Hooks Pattern: Custom hooks to share logic.
Render Props Pattern: Pass render logic as props.
Compound Component Pattern: Used in UI libraries like
Headless UI.
44. Context API vs Redux
Context API is simpler and built-in, good for small to medium apps.
Redux is more powerful with middleware, dev tools, and supports
large-scale state management with more control and structure.
45. Prop Types in React (Validation)
import PropTypes from 'prop-types';
function MyComponent({ name }) {
return <h1>{name}</h1>;
}
[Link] = {
name: [Link],
};
PropTypes helps validate props' types during development,
preventing bugs due to incorrect usage.
46. What are React Mixins?
Mixins are objects that contain shared code and can be reused in
multiple components. They were used in older React with
createClass but are now deprecated in favor of HOCs and hooks.
47. What are the Different Hooks You Have Used?
useState – manage local state
useEffect – side effects
useRef – reference DOM elements
useContext – consume context
useReducer – complex state logic
useMemo, useCallback – performance optimization
useLayoutEffect, useImperativeHandle, useId – advanced use
cases
48. What are Render Props in React?
function DataProvider({ render }) {
const data = { name: "John" };
return render(data);
}
// Usage
<DataProvider render={(data) => <p>{[Link]}</p>} />
Render props are a technique where a function is passed as a prop
to share code between components.
49. Different Types of Imports and Exports
// Named export
export const a = 10;
// Default export
export default MyComponent;
// Import
import { a } from './file';
import MyComponent from './file';
Named exports allow multiple exports per file, while default
exports allow only one per file.
50. createElement vs cloneElement
[Link] creates a new React element from scratch.
[Link] clones and optionally modifies an existing
element, useful when injecting props into children.
51. When to Use useState vs useReducer?
Use useState for simple state logic like toggles or form fields. Use
useReducer when state transitions are complex or depend on
previous values—like managing forms, tabs, or authentication.
52. What are Protected Routes in React?
<Route
path="/dashboard"
element={isAuth ? <Dashboard /> : <Navigate to="/login" />}
/>
Protected routes restrict access to certain components based on
user authentication. Use React Router with conditional rendering
or wrapper components to protect them.
53. What is React Router Has Context Menu?
React Router doesn’t provide a native context menu feature, but
you can implement a custom right-click menu using the Context
API or state, showing it based on route or user interaction.
✅ Let me know if you'd like a PDF/Markdown version of all 53
answers or want to practice mock interview-style questions next!
[Link]
This SQL code creates the schema for a Task Management System
using a relational database. It includes tables for users, projects,
tasks, comments, and project memberships. Below is a detailed
explanation of each part, followed by possible full-stack interview
questions (both backend and frontend) based on this schema.
1. Explain the database design. Why did you separate tasks and
comments?
Answer:
The database is normalized to avoid redundancy and ensure
scalability. Tasks and comments are separated because a task can
have multiple comments, which is a one-to-many relationship.
This structure keeps the data organized and allows comments to
be queried or managed independently from the task logic.
4. How would you query all tasks assigned to a user, sorted by
due date?
sql
CopyEdit
SELECT * FROM tasks
WHERE assigned_to = ?
ORDER BY due_date ASC;
ow would you fetch all members of a given project along with
their roles?
sql
CopyEdit
SELECT [Link], [Link]
FROM project_members pm
JOIN users u ON pm.user_id = [Link]
WHERE pm.project_id = ?;
Changes
In [Link]
async findById(userId){
try {
const query ='SELECT id,username,email,full_name FROM users
WHERE id=?'
const [users]=await [Link](query,[userId]);
return user[0]|| null
; } catch (error) {
[Link]('Error finding user by ID:', error);
throw new Error('Failed to find user');
}
}
async updateUser(userId,{fullName,email}){
try {
const query= ‘UPDATE users SET full_name=?,email=?,WHERE id=?’
await [Link](query,[full]
} catch (error) {
[Link]('Error updating th user',error);
throw new Error('Failed')
}
}
Use await here
async assignTask(taskId, userId) {
const query = 'UPDATE tasks SET assigned_to = ? WHERE id = ?';
let connection;
try {
connection = await [Link](); // ✅ await here
await [Link](query, [userId, taskId]); // ✅ await
execute
return { success: true };
} catch (error) {
[Link]('Error assigning task:', error);
return { success: false, message: 'Database error', error };
} finally {
if (connection) [Link](); // ✅ release only if
connection was successful
}
}