Coding Challenge: Faculty Features
In this challenge assignment, you will apply your knowledge of Express, EJS, and MVC architecture to improve error handling and build a new faculty directory system. This assignment builds on the route parameter concepts and MVC structure you learned in previous assignments.
The challenge consists of two main tasks that will help you practice:
- Building a faculty directory system using the same route parameter patterns you learned with the course catalog
- Enhancing the faculty directory with query parameter sorting
You should already be in the habit of committing your changes regularly. If you haven't done so, make sure to commit your work before starting this assignment. This will help you track your progress and revert changes if needed.
Git Branch Management
For this assignment, you will learn to use Git branches to keep your experimental work separate from your main codebase. Creating a branch allows you to work on new features without affecting your working main branch, and you can easily switch back if something goes wrong.
Create a new branch for this assignment work:
# Create and switch to a new branch for this assignment
git checkout -b faculty-directory
You can verify you are on the correct branch using:
git branch
# or for more details
git status
Work on the assignment in this branch. If you need to switch back to your main branch for any reason, use:
git checkout main
And to switch back to your assignment branch:
git checkout faculty-directory
After completing all tasks in this assignment, you can merge your changes back to your main branch:
# First commit your changes in the faculty-directory branch
git add .
git commit -m "Complete faculty directory system"
# Switch to main branch
git checkout main
# Merge changes from faculty-directory branch
git merge faculty-directory
# Push to remote repository
git push
# Optionally delete the feature branch
git branch -d faculty-directory
Challenge Instructions
1. Build a Faculty Directory System
You will create a new faculty directory system that uses the same route parameter patterns you learned with the course catalog. This will be a completely separate system that practices the same technical concepts with different content, preventing you from simply copying and pasting your course catalog code.
The faculty directory will include a list of all faculty members and individual faculty profile pages, using routes like /faculty and /faculty/:facultyId.
Directory Structure Setup
First, create the MVC structure for your faculty system. Add these directories and files to your existing project:
src/
├── controllers/
│ ├── catalog/
│ │ └── catalog.js
│ ├── faculty/ # New!
│ │ └── faculty.js # New!
│ ├── index.js
│ └── routes.js
├── models/
│ ├── catalog/
│ │ └── catalog.js
│ └── faculty/ # New!
│ └── faculty.js # New!
└── views/
├── ...
└── faculty/ # New!
├── list.ejs # New!
└── detail.ejs # New!
views/ directory to match this structure. We will fix that soon, but starting now, all new code such as the new faculty page will follow the correct MVC pattern.
Faculty Data Model
Create src/models/faculty/faculty.js and add this faculty data and helper functions:
// Faculty data object
const faculty = {
'brother-jack': {
name: 'Brother Jack',
office: 'STC 392',
phone: '208-496-1234',
email: 'jackb@byui.edu',
department: 'Computer Science',
title: 'Associate Professor'
},
'sister-enkey': {
name: 'Sister Enkey',
office: 'STC 394',
phone: '208-496-2345',
email: 'enkeys@byui.edu',
department: 'Computer Science',
title: 'Assistant Professor'
},
'brother-keers': {
name: 'Brother Keers',
office: 'STC 390',
phone: '208-496-3456',
email: 'keersb@byui.edu',
department: 'Computer Science',
title: 'Professor'
},
'sister-anderson': {
name: 'Sister Anderson',
office: 'MC 301',
phone: '208-496-4567',
email: 'andersons@byui.edu',
department: 'Mathematics',
title: 'Professor'
},
'brother-miller': {
name: 'Brother Miller',
office: 'MC 305',
phone: '208-496-5678',
email: 'millerb@byui.edu',
department: 'Mathematics',
title: 'Associate Professor'
},
'brother-thompson': {
name: 'Brother Thompson',
office: 'MC 307',
phone: '208-496-6789',
email: 'thompsonb@byui.edu',
department: 'Mathematics',
title: 'Assistant Professor'
},
'brother-davis': {
name: 'Brother Davis',
office: 'GEB 205',
phone: '208-496-7890',
email: 'davisb@byui.edu',
department: 'English',
title: 'Professor'
},
'brother-wilson': {
name: 'Brother Wilson',
office: 'GEB 301',
phone: '208-496-8901',
email: 'wilsonb@byui.edu',
department: 'History',
title: 'Associate Professor'
},
'sister-roberts': {
name: 'Sister Roberts',
office: 'GEB 305',
phone: '208-496-9012',
email: 'robertss@byui.edu',
department: 'History',
title: 'Assistant Professor'
}
};
const getFacultyById = (facultyId) => {
// TODO: Look up faculty member by ID, return null if not found
};
const getSortedFaculty = (sortBy) => {
// TODO: Validate sortBy parameter (name, department, or title), default to 'name' if invalid
// Create an array of all faculty members
const facultyArray = [];
for (const key in faculty) {
// Add each individual faculty object to the array
facultyArray.push({...faculty[key], id: key});
}
// Sort the array by the chosen property
facultyArray.sort((a, b) => {
// Compare the property values
if (a[sortBy] < b[sortBy]) {
return -1;
}
if (a[sortBy] > b[sortBy]) {
return 1;
}
return 0; // They are equal
});
// Return the sorted array
return facultyArray;
};
export { getFacultyById, getSortedFaculty };
Alternative: Individual Export Method
If you prefer to export functions as you define them, you can use this approach instead:
export const getAllFaculty = () => {
// TODO: Return the faculty object
};
export const getFacultyById = (facultyId) => {
// TODO: Look up faculty member by ID, return null if not found
};
export const getSortedFaculty = (sortBy) => {
// TODO: Validate sortBy parameter (name, department, or title), default to 'department' if invalid
// Create an array of all faculty members
const facultyArray = [];
for (const key in faculty) {
// Add each individual faculty object to the array
facultyArray.push(faculty[key]);
}
// Sort the array by the chosen property
facultyArray.sort((a, b) => {
// Compare the property values
if (a[sortBy] < b[sortBy]) {
return -1;
}
if (a[sortBy] > b[sortBy]) {
return 1;
}
return 0; // They are equal
});
// Return the sorted array
return facultyArray;
};
Build the Faculty Controllers
Create src/controllers/faculty/faculty.js with route handlers for faculty list and detail pages. Follow the same pattern you used for the course controllers:
- Import the faculty model functions
- Create a
facultyListPagefunction that renders the faculty list page - Create a
facultyDetailPagefunction that uses route parameters to look up individual faculty - Include proper error handling for invalid faculty IDs
- Export both functions
Create Faculty Routes
Update your src/routes.js file to include the faculty routes:
- Import your faculty controllers
- Add a
/facultyroute for the faculty list - Add a
/faculty/:facultyIdroute for individual faculty details
Build the Faculty Views (Including Styles)
To help you focus on the backend logic, we have provided starter template files and CSS styles. Attempt to build everything yourself first to maximize your learning, but if you get stuck on the frontend presentation, you can download these files as a starting point. You can reverse-engineer the EJS templates to understand the data structure your controllers need to provide.
Create the faculty templates following the same structure as your course catalog templates:
Faculty List Template (src/views/faculty/list.ejs):
- Display all faculty members in a grid or list format
- Make each faculty member's name link to their detail page
- Show basic information like name, department, and title
- Include proper navigation back to main site
Faculty Detail Template (src/views/faculty/detail.ejs):
- Display detailed information about the faculty member
- Include name, office, phone, email, department, and title
- Provide a link back to the faculty list
- Follow the same styling patterns as your course detail pages
Update Navigation
Add a link to the faculty directory in your site navigation. Update your header.ejs partial:
<nav>
<ul>
...
<li><a href="/faculty">Faculty Directory</a></li>
</ul>
</nav>
Testing Your Implementation
Test your faculty directory by visiting these URLs:
- http://127.0.0.1:3000/faculty - Should show list of all faculty
- http://127.0.0.1:3000/faculty/brother-jack - Should show Brother Jack's details
- http://127.0.0.1:3000/faculty/sister-anderson - Should show Sister Anderson's details
- http://127.0.0.1:3000/faculty/invalid-person - Should show 404 error page not your 500 error page
Testing Faculty Sorting
Test your sorting functionality with these URLs:
- http://127.0.0.1:3000/faculty - Default sorting by name
- http://127.0.0.1:3000/faculty?sort=department - Sorted by department
- http://127.0.0.1:3000/faculty?sort=title - Sorted by title
- http://127.0.0.1:3000/faculty?sort=name - Sorted by name
- http://127.0.0.1:3000/faculty?sort=invalid - Should not show an error but instead default to sorting by name
Notice how you're applying the same query parameter patterns you learned with course section sorting. This repetition helps solidify your understanding of how Express handles different types of URL parameters.
This faculty directory uses the exact same technical patterns you learned with the course catalog: route parameters, object lookup, template rendering, and error handling. The only difference is the data structure and content. If you understand how the course system works, you can apply the same concepts here.
Submission Requirements
When you have completed the assignment:
-
Record a brief video demonstration (2-3 minutes preferred, 5 minutes maximum) showing:
- Your error handling implementation in both development and production modes
- Your faculty directory list and detail pages working correctly
- Faculty list sorting functionality
- Navigation between the course catalog and faculty directory systems
- Upload your video to YouTube (as unlisted), OneDrive, Google Drive, or another file sharing service
- If you are using a cloud storage solution, ensure the link is set to "viewable by anyone with the link". Any submissions requiring permission or access requests will receive a zero.
-
Do not forget to restore your
.envfile to development mode after creating the video
Remember to follow coding best practices throughout this assignment:
- Using consistent naming conventions
- Organizing your code according to MVC architecture
- Adding comments to explain complex sections
- Following separation of concerns principles
Hints and Tips
Here are some additional hints to help you complete the assignment:
-
Faculty Directory (Task 1):
- Look at your existing course controllers and templates as examples
- The faculty lookup pattern is identical to course lookup:
faculty[facultyId] - Test each piece incrementally: model functions first, then controllers, then templates
- Don't forget to handle the case where someone requests an invalid faculty ID
-
Faculty Sorting (Task 2):
- Review how you implemented course section sorting for guidance
- Remember to convert the faculty object to an array before sorting
- Use JavaScript's
Object.values()andsort()methods
If you encounter issues, take a systematic approach:
- Check your server console for error messages and stack traces
- Verify your file paths and import statements are correct
- Test one route at a time before moving to the next
- Compare your faculty implementation to your working course implementation
Key Concepts Summary
This challenge assignment reinforced core Express and MVC concepts through practical repetition. You practiced route parameters, object lookup patterns, template rendering, query parameter handling, and error management using a completely different domain from your course catalog.
The faculty directory system demonstrates how the same technical patterns can be applied to different types of data and use cases. Understanding these transferable patterns is essential for building larger, more complex web applications.
By implementing environment-specific error handling, you also learned important production deployment considerations that professional developers must address when building real-world applications.