0% found this document useful (0 votes)
7 views

Terminal Exam - Web Engg - SP23 - Solution (1) (1)

The document outlines the final exam for the SE-3003 Web Engineering course at the National University of Computer and Emerging Sciences, detailing instructions and question formats. It includes multiple-choice questions on React concepts, CRUD operations for a Clinic System application using ExpressJS, and code-related queries. The exam consists of three questions with a total of 100 marks, and specific guidelines for answering are provided.

Uploaded by

ahmedmukarram6
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views

Terminal Exam - Web Engg - SP23 - Solution (1) (1)

The document outlines the final exam for the SE-3003 Web Engineering course at the National University of Computer and Emerging Sciences, detailing instructions and question formats. It includes multiple-choice questions on React concepts, CRUD operations for a Clinic System application using ExpressJS, and code-related queries. The exam consists of three questions with a total of 100 marks, and specific guidelines for answering are provided.

Uploaded by

ahmedmukarram6
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 27

National University of Computer and Emerging Sciences

FAST School of Computing Spring-2023 Islamabad Campus

SE-3003: Web Engineering Serial No:


Final Exam

Wednesday, 24th May, 2023 Total Time: 3 Hour


Course Instructors Total Marks: 100
Zaheer Sani, Irfan Ullah
________________
Signature of Invigilator

____________________ ____________ _____________ __________________


Student Name Roll No. Course Section Student Signature

DO NOT OPEN THE QUESTION BOOK OR START UNTIL INSTRUCTED.

Instructions:
1. Attempt on question paper. Attempt all of them. Read the question carefully, understand the
question, and then attempt it.
2. Use Rough Work space to finalize the answer and then write in the given space. Cutting
and overwriting will not be evaluated, so carefully plan the answers.
3. Write optimized and minimal code to achieve the desired functionality. Writing poor code
will not get full marks. It is not all about ‘it works’, it should work in the best optimal way.
4. After asked to commence the exam, please verify that you have Eighteen (18) different
printed pages including this title page. There are a total of 3 questions.
5. Use permanent ink pens only. Any part done using soft pencil will not be marked and
cannot be claimed for rechecking.

Q-1 Q-2 Q-3 Total

Marks Obtained

Total Marks 20 20 60 100


Question 1 [20 x 1 = 20 Marks]

Fill the table for the correct option in uppercase letters ONLY. Overwriting and cutting will not give
you any score.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
B
or D C D A D A A A D C B B C B A B A B C
C

1. In React, which of the following is the correct way to update the state based on the previous state?
a) this.state = state + 1;
b) this.setState({ count: this.state.count + 1 });
c) this.setState(prevState => ({ count: prevState.count + 1 }));
d) this.setState({ count: this.state.count++ });

2. How can you conditionally render content in a React functional component?


a) Using the "if-else" statement.
b) Using the "switch" statement.
c) Using the "render" method.
d) Using JavaScript expressions within JSX.

3. Which block of code or a hook is used to fetch data from an API in a React functional component?
a) Using the "fetch" method inside the component's render function.
b) Using the "componentDidMount" lifecycle method.
c) Using the "useEffect" hook.
d) Using the "fetch" method at the root of a component.

4. How can you pass data from a child component to its parent component in React?
a) By using the "this.props" object.
b) By using the "setState" method.
c) By using the "useContext" hook.
d) By passing a callback function as a prop.

5. What is the purpose of the "useReducer" hook in React?


a) To manage local state in functional components.
b) To handle asynchronous operations in functional components.
c) To synchronize state between multiple components.
d) To control the rendering behavior of functional components.

6. What is the role of the useContext hook in React?


a) To subscribe to changes in context values.
b) To create a new context for sharing state.
c) To consume context values within functional components.
d) To provide context values to child components.

7. When should you use the useReducer hook instead of the useState hook in React?
a) When managing complex state logic or multiple related values.
b) When working with form inputs.
c) When handling asynchronous operations.
d) When using context in functional components

Page 2 of 27
8. How can you trigger a re-render of a React component?
a) By changing the state of a component.
b) By modifying the component's props.
c) By using the render method.
d) React components automatically re-render when their state or props change

9. How can you handle form inputs in React?


a) By using the onChange event and updating the component's state.
b) By using the onSubmit event and updating the component's state.
c) By directly modifying the DOM using JavaScript.
d) By using the useState hook to manage the form state.

10. Which React hook is commonly used to handle complex state logic in functional components?
a) useState
b) useEffect
c) useContext
d) useReducer

11. What is the purpose of the useEffect hook in ReactJS?


a) To handle user input in forms.
b) To update the component's state.
c) To perform side effects like data fetching or subscriptions.
d) To define event listeners for keyboard events.

12. What is the React Context API used for?


a) Managing state in functional components
b) Sharing data between components without passing props explicitly
c) Handling asynchronous operations in React applications
d) Optimizing the performance of React applications

13. How is data provided to components using the React Context API?
a) By passing data as props from parent to child components
b) By defining a context object and using a Provider component to wrap the desired components
c) By using Redux for state management
d) By using the useState hook to create a global state object

14. What is the main benefit of using Redux in a React application?


a) It simplifies component rendering and lifecycle management
b) It improves the performance of React components
c) It provides a centralized and predictable state management solution
d) It enables server-side rendering of React components

15. What is the purpose of the "dispatch" function in Redux?


a) It triggers a re-render of the connected React component
b) It updates the Redux store by applying the specified action
c) It performs an API request to fetch data for the Redux store
d) It connects React components to the Redux store

16. What is the primary routing component used in React Routing v6?
a) BrowserRouter
b) Switch
c) Router
d) Route

Page 3 of 27
17. Which hook is used to navigate programmatically in React Routing v6?
a) useHistory
b) useNavigate
c) useLocation
d) useParams

18. How do you define a route with parameters in React Routing v6?
a) <Route path="/users/:id" element={<UserDetail />} />
b) <Route path="/users/{id}" element={<UserDetail />} />
c) <Route path="/users/:id" component={UserDetail} />
d) <Route path="/users/{id}" component={UserDetail} />

19. How do you define a nested route in React Routing v6?


a) By using the <NestedRoute> component.
b) By nesting <Route> components inside the parent route.
c) By using the children prop on the parent route.
d) By defining a separate route configuration for the nested route.

20. It is a recommended approach to store JWT Secrets an env file. _______ package is used to read env file?
a) jsontoken
b) jwt
c) dotenv
d) none of the above

Page 4 of 27
Question 2 [5 x 4 = 20 Marks]

Consider a Clinic System application that manages the data of doctors using ExpressJS and APIs. The
doctor entity has the following attributes: Name, Designation, and Specialization. You are tasked with
implementing the API routes for performing CRUD operations on the doctors' data.

While writing code, any data source can be selected but specify which data source is used in the
implementation.

Please provide the sample API calls for the routes that need to be implemented in ExpressJS to achieve
the following functionalities:

1) Retrieve all doctors' information:


Endpoint: GET /api/doctors
Sample Request: GET /api/doctors
Sample Response:
[
{
"name": "Dr. John Smith",
"designation": "Senior Consultant",
"specialization": "Cardiology"
},
{
"name": "Dr. Sarah Johnson",
"designation": "Pediatrician",
"specialization": "Pediatrics"
},
...
]

const express = require('express');


const app = express();
app.use(express.json());

// Sample data for doctors


let doctors = [
{
id: 1,
name: "Dr. John Smith",
designation: "Senior Consultant",
specialization: "Cardiology"
},

Page 5 of 27
{
id: 2,
name: "Dr. Sarah Johnson",
designation: "Pediatrician",
specialization: "Pediatrics"
}
];

// Retrieve all doctors' information


app.get('/api/doctors', (req, res) => {
res.json(doctors);
});

Page 6 of 27
2) Retrieve a specific doctor's information:
Endpoint: GET /api/doctors/:id
Sample Request: GET /api/doctors/123
Sample Response:
{
"name": "Dr. John Smith",
"designation": "Senior Consultant",
"specialization": "Cardiology"
}

// Retrieve a specific doctor's information


app.get('/api/doctors/:id', (req, res) => {
const doctorId = parseInt(req.params.id);
const doctor = doctors.find(doc => doc.id === doctorId);

if (doctor) {
res.json(doctor);
} else {
res.status(404).json({ error: 'Doctor not found' });
}
});

3) Add a new doctor:


Endpoint: POST /api/doctors
Sample Request: Sample Response:
POST /api/doctors {
Content-Type: application/json "id": "234",
"name": "Dr. Emily Brown",
{ "designation": "Dermatologist",
"name": "Dr. Emily Brown", "specialization": "Dermatology"
"designation": "Dermatologist", }
"specialization": "Dermatology"
}

// Add a new doctor


app.post('/api/doctors', (req, res) => {
const { name, designation, specialization } = req.body;

Page 7 of 27
const newDoctor = {
id: doctors.length + 1,
name,
designation,
specialization
};

doctors.push(newDoctor);

res.status(201).json(newDoctor);
});

Page 8 of 27
4) Update an existing doctor's information:
Endpoint: PUT /api/doctors/:id
Sample Request: Sample Response:
PUT /api/doctors/123 {
Content-Type: application/json "id": "123",
"name": "Dr. John Smith",
{ "designation": "Consultant",
"name": "Dr. John Smith", "specialization": "Cardiology"
"designation": "Consultant", }
"specialization": "Cardiology"
}

// Update an existing doctor's information


app.put('/api/doctors/:id', (req, res) => {
const doctorId = parseInt(req.params.id);
const { name, designation, specialization } = req.body;

const doctor = doctors.find(doc => doc.id === doctorId);

if (doctor) {
doctor.name = name;
doctor.designation = designation;
doctor.specialization = specialization;

res.json(doctor);
} else {
res.status(404).json({ error: 'Doctor not found' });
}
});

5) Delete a doctor:
Endpoint: DELETE /api/doctors/:id
Sample Request: DELETE /api/doctors/123
Sample Response:
{
"id": "123",
"message": "Doctor deleted successfully."
}

Page 9 of 27
Note: Please provide the sample API calls for the routes mentioned above, considering the appropriate
HTTP methods and endpoints.
app.delete('/api/doctors/:id', (req, res) => {
const doctorId = parseInt(req.params.id);

const doctorIndex = doctors.findIndex(doc => doc.id === doctorId);

if (doctorIndex !== -1) {


doctors.splice(doctorIndex, 1);
res.json({ id: doctorId, message: 'Doctor deleted successfully' });
} else {
res.status(404).json({ error: 'Doctor not found' });
}
});

Page 10 of 27
Question 3 [60 Marks]

Answer following questions.

1) Consider following code:

export default function App() {

const [ready, setReady] = useState(false);

console.log('State is Ready!')

useEffect(() => {

console.log("Component rendered successfully");

}, [ready]);

console.log("Returning JSX")

return (

<div>

<button onClick={() => setReady(true)}>Click me</button>

<p>I'm { ready? 'Ready!' : 'Not Ready!'}</p>

</div>

);

a) What will be the output on console when component is rendered first time? (2 Marks)

State is Ready!

Returning JSX

Component rendered successfully

b) What will be the output on console when button is clicked for the first time? (2 Marks)

State is Ready!

Returning JSX

Page 11 of 27
c) What will be printed on the web page when the button is clicked for the first time? (2 Mark)

Ready!

Page 12 of 27
2) What will be printed on the screen? If there is any error, specify that. (2 Marks)

export default function App() {


const items = [
{ id: 1, text: "Item 1" },
{ id: 2, text: "Item 2" },
];
const listItems = items.map((item, index) => <li key={index}>{item.text}</li>);
return <ul>{listItems}</ul>;
}

Output:

 Item 1

 Item 2

3) Write the missing piece of the code. (2 Marks)

function PostList({__posts_}) {
return (
<div>
<h2>Posts</h2>
{ posts.length === 0 ? (
<p>No posts available.</p>
):(
<ul>
{ posts.map(post => (
<li key={ posts.id }>
<h3>Title: { posts.title}</h3>
<p>Body: { posts.body }</p>
</li>
))}

Page 13 of 27
</ul>
)}
</div>
);
}

export default function App() {


const postlist = [{ id: 1, title: 'Title 1', body: 'Body of Post 1' }]
return <PostList posts={postlist} />
}

Page 14 of 27
4) Consider following code which desires to retrieves messages from the API endpoint. It is required
to fetch the messages only once when component is rendered. Complete the code to achieve
desired functionality. (10 Marks)

1 const ChatWindow = () => {


2
3 const fetchMessages = async () => {
4 try {
5 const response = await fetch('/api/messages');
6 const data = await response.json();
7
8 } catch (error) {
9 console.log('Error fetching messages:', error);
10 }
11 };
12
13 return (
14 <div>
15 {messages.map((message, index) => (
16 <div key={index}>{message.text}</div>
17 ))}
18 </div>
19 );
20 };

Write missing code to complete the functionality of the component. Specify the line number to insert
the code. Do not rewrite the complete code again and do not modify anything in existing code.

Note: It is an assumption that Insertion of the code will not effect the line numbers specified in the
given code. So, if you insert something on line number 5 will not bring rest of the code in next line.

Insert Code at Line # 2

const [messages, setMessages] = useState([])

useEffect(() => {
fetchMessages();
}, [])

Page 15 of 27
Insert Code at Line # 7

setMessages(data);

Page 16 of 27
5) Update the code provided in solution of above problem to fetch the messages from the server after
one second when component is rendered. (5 Marks)

const [messages, setMessages] = useState([])


useEffect(() => {

setTimeout(() => {
fetchMessages()
}, 1000)

}, [])

6) Consider following code.

a) Complete the given code. (5 Marks)

const Parent = (props) => {


const [user, setUsers] = useState([]);

return (
<ChildA user= { user } />
)
}

const ChildA = (props) => {


return (
<ChildB user= { props.user } />
)
}

Page 17 of 27
const ChildB = (props) => {
return (
<ChildC user= { props.user } />
)
}

const ChildC = (props) => {


return (
<h1>Username is: {props.user} </h1>
)
}

b) What is the issue with this approach, how it can be avoided? (5 Marks)

To receive username in ChildC component, we need to pass username in the chain of


components through props. And when the nesting of the components get more complex, it will
be become more difficult to pass the props.

To avoid this, we can use Context API provided by React JS

c) Re-write the code with the react prescribed approach to pass the props to the last component in the tree.
(5 Marks)

const UserContext = createContext(null);

const Parent = () => {


const [user, setUsers] = useState([]);

return (
<UserContext.Provider value={user}>
<ChildA />
</UserContext.Provider>
)
}

const ChildA = () => {

Page 18 of 27
return (
<ChildB />
)
}

const ChildB = () => {


return (
<ChildC />
)
}

const ChildC = () => {


const username = useContext(UserContext)
return (
<h1>Username is: {username} </h1>
)
}

Page 19 of 27
7) Consider a complex multi-level navigation structure in a React application using React Router. The
application consists of the following routes: (10 Marks)

Home ("/")
Products ("/products")
Product Details ("/products/:id")
Categories ("/categories")
Category Details ("/categories/:id")
Admin Dashboard ("/admin/dashboard")
Admin Products ("/admin/products")
Admin Categories ("/admin/categories")

Code a react router for the above pages. When coding React Router, group the Admin Routes.

Note: Assume that the pages/components already exist, you can assume any name for these
pages/components.

export default function MyApp() {

return (

<>

<Routes>

<Route path="/" element={<Home />} />

<Route path="/products" element={<Products />} />

<Route path="/products/:id" element={<Product />} />

<Route path="/categories" element={<Categories />} />

<Route path="/categories/:id" element={<Category />} />

<Route path="/admin">

<Route path="dashboard" element={<AdminDashboard />} />

<Route path="products" element={<AdminProducts />} />

<Route path="categories" element={<AdminCategories />} />

</Route>

</Routes>

</>

Page 20 of 27
);

Page 21 of 27
8) In a social media application, where a logged in user posts are stored in application level state. A
post has id, title and description.

a) Code a reducer which has an initial state, relevant actions for fetching and storing posts, and
exports (reducer and actions). (4 Marks)

import { createSlice } from '@reduxjs/toolkit'

export const postSlice = createSlice({


name: 'posts',
initialState: {
posts: [],
},
reducers: {
fetch_posts: (state) => {
fetch(url).then(res => res.json()).then(res => {
state.posts = res;
})
},
},
})

// Actions
export const { fetch_posts } = postSlice.actions

export default postSlice.reducer

b) create a store and register your reducer (2 Marks)

import { configureStore } from '@reduxjs/toolkit'


import postreducer from './postReducer.js'

export default configureStore({


reducer: {
posts: postreducer,
},
})

c) Provide the store to application (2 Marks)

// index.js (entry point of the application)

Page 22 of 27
import store from './app/store'
import { Provider } from 'react-redux'

const root = ReactDOM.createRoot(document.getElementById('root'))

root.render(
<Provider store={store}>
<App />
</Provider>
)

d) Display the state in ProfileComponent (2 Marks)

import React, { useEffect } from "react";


import { useSelector, useDispatch } from "react-redux";
import {
fetch_posts
} from "./postsReducer";

const ProfileComponent = () => {


const posts = useSelector((state) => state.posts.posts);
const dispatch = useDispatch();

useEffect(() => {
// Dispatch an action to fetch posts
dispatch(fetch_posts());

}, [posts]);

return (
<div>
<h1>Profile</h1>
{posts.map((post) => (
<div key={post.id}>
<h2>{post.title}</h2>

Page 23 of 27
<p>{post.description}</p>
</div>
))}
</div>
);
};

export default ProfileComponent;

Page 24 of 27
Rough Work

Page 25 of 27
Rough Work

Page 26 of 27
Rough Work

Page 27 of 27

You might also like