Color Mode

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:

Commit Your Changes

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!
    
If you've been paying close attention to our transition to the MVC (Model View Controller) pattern, you may have noticed that we have not yet fully refactored the 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:

Create Faculty Routes

Update your src/routes.js file to include the faculty routes:

Build the Faculty Views (Including Styles)

Starter Files Available

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):

Faculty Detail Template (src/views/faculty/detail.ejs):

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:

Testing Faculty Sorting

Test your sorting functionality with these URLs:

Pattern Recognition

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.

Building on What You Know

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:

  1. 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
  2. Upload your video to YouTube (as unlisted), OneDrive, Google Drive, or another file sharing service
  3. 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.
  4. Do not forget to restore your .env file 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:

If you encounter issues, take a systematic approach:

  1. Check your server console for error messages and stack traces
  2. Verify your file paths and import statements are correct
  3. Test one route at a time before moving to the next
  4. 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.