Developing the Playlister App
HW 1: 1st Technology Learning Assignment - GUIs & JavaScript
The Big Picture
This semester you will be creating a CRUD Web Application using the MERN stack for entering and editing data associated with music playlists, meaning one can use the application to create a playlist of our favorite songs and then play the songs in our very own music player. Note that YouTube will be providing the songs and the API for our player. When completed the program will let the user login to an online account, create playlists, find lists made by others, like or dislike lists, comment on them, and store all created and edited work in an online database. We'll also have a feature where one can import and export playlists and even aggregate data of note, like the frequency of specific songs, etc.) This will be a semester-long project, so before we code our solution, we first will have to learn all about the necessary technologies to use. This is a common first step in Software Engineering, so get used to it. We will then design our solution, and then code. The HWs are divided up as follows:
- HW 1 - 1st Technology Learning Assignment - GUIs & JavaScript: In this assignment you will learn about building a GUI using HTML/CSS/JSON/JavaScript, i.e. front-end Web standards. You will also learn how to implement an undo/redo system for such an application as well as how to store data in a browser's local storage.
- HW 2 - 2nd Technology Learning Assignment - Frameworks: Here you'll learn about using a CSS Framework (Tailwind) and a Front-End Framework (React) to make the very same application as in HW 1.
- HW 3 - 3rd Technology Learning Assignment - Back-End API with NoSQL Database: Here you'll learn expand the app into a full-stack application by adding a back-end API that will store playlists in a NoSQL Database (Mongo).
- HW 4 - 4th Technology Learning Assignment - User Accounts and Secure Back-End API with Relational Database: Here we'll use what we learn about Web security to create an accounts management system. In addition we'll change the back-end database to use a Relational Database (MySQL). Note, solutions for HWs 1 - 4 will be provided by the professor and you will be able to use any code you like from those solutions in your own final project implementation.
- HW 5 - UML Design: Here you will be given a product specification, i.e. what to build, and you will have to design a solution, which you'll do using UML diagrams.
- Final Project - Playlister - And finally, you will implement your project, Playlister which will borrow heavily from HWs 1 - 4 but will also work such that users can share and find playlists and view aggregated statistics as well as actually play the songs in our own local player.
HW 1 Setup
Now, to get the starting point for HW 1 up an running do the following:
- Download and install Visual Studio Code. This is the IDE we will be using this semester for authoring source code.
- Download and install Firefox. The TAs will use this Web browser for testing this semester so it is to your advantage to use it as well.
- Create a local directory called 316-HW1-Playlister on your computer where you will do your work for HW 1. Note that you will use a different directory for the next assignment. Please be sure this is a real directory, not just a symbolic path. If you are on Windows, put it somewhere in your My Documents directory, and not on One Drive.
- Start Visual Studio Code and choose File -> Open Folder. Navigate to your newly created directory from the previous step and select it. The directory should be empty, so it should simply open up an empty directory in your IDE.
- Make a GitHub account if you don't already have one. Everything you do this semester must be documented in your GitHub commits and thus it should document your gradual progress on a given assignment. Remember, only commit working code, and commit after each bit of progress, like adding a feature of fixing a bug or updating style or layout. Once you have an account, create your own GitHub repository and make sure it's private. It should be named 316-HW1-LastNameFirstName where you substitute your own last and first name. Note, you'll make a different repository for each HW but only worry about HW 1 for now.
- Go back to Visual Studio code and select Terminal -> New Terminal, which will open a CLI (Command Line Interface) at the bottom of the UI. In the Terminal, type git clone https://github.com/TheMcKillaGorilla/316-HW1-Playlister . and be sure to include the period at the end. This will get the starting code for your assignment.
- You will now want to hook up your local repository to your own GitHub repository which you already made. To do so, first go to your browser and copy the complete link to your newly created repo. Then go to the terminal and type git remote set-url origin https://github.com/your-username/316-HW1-LastNameFirstName.git where the URL is your copied link, so your-username would be your GitHub name and LastNameFirstName would be your actual last and first name.
- Now you want to push your code to your remote repo. To do so, type git push -u origin main
- You should be able to verify that the code has been pushed by refreshing the repo in your browser and in the Terminal by typing git remote -v which should list your repo. Note again, you must use GitHub throughout your development process for all assignments this semester and it's a good policy to use it (or something like it) for all projects you work on.
- When you end up making changes to the project, you can use the following commands from your Terminal:
- git add . - this is for when you add a new file to the repo
- git commit -m "My Message" - a commit is when you make a change that works or fixes something. Of course "My Message" should describe the change so others (and yourself) could understand it in the future.
- git push - commit will commit code to your local repo, push will then send one or more commits to your GitHub repo, updating it there.
- Note, this is a Node.js project and so the first thing you'll need to do is install Node. After you have done that you'll need to install the necessary libraries for HW 1. To do so, in the Terminal, type npm install which will retrieve all the used frameworks in the project.
- Time to run the application. To do so, open package.json and you will see under scripts that there is one called start. To run this script type npm start. Note, all it does is start a local Web server which you could simply run directly without use of the script command by typing node server.js. Note that server.js uses express (the E in MERN) to create a simple Web server for serving static content. We'll use Express for more complicated things starting in HW 3. When you run this command it should print out Server running at http://localhost:3000 and you should be able to view the Web application using that URL in your Firefox (or any) browser.
- Once the application is up and running in Firefox you'll want to get accustomed to debugging using a Web browser. This is a very important skill. Again, you are welcome to use another browser but the TAs will do testing using Firefox. To do so, go to the ☰ menu in the top right corner and select More Tools and then click on Web Developer Tools. There are tabs for viewing and editing anything and everything related to the page. Inspector has the DOM, Console displays output. Debugger lets you actively debug your program. There are also tabs for keeping track of network communications, threads, style, Local Storage (which we'll use in this assignment) and all manner of performance metrics like CPU usage and memory. The first thing you should do is go to the Debugger Tab and put a breakpoint at the first point of entry for the program, which inside the window.onload callback function inside of PlaylisterApp.js. Put a breakpoint there and refresh the page. See if you can walk through the complete initialization of the site. Try putting breakpoints inside callback functions found in PlaylisterController.js and then trigger those events by using the applicfation in order to see them operate.
Playlister - Becoming Code Literate
In this assignment I'll be giving you a whole heap of code that is partially working but incomplete. It is vital that you start by learning how it all works. Do your best to figure out how all the pieces fit together and what each piece does. Writing carefully designed, modular code is one of the most important skills for you to develop this semester, and the code I have provided tries to encourage you to do just that by employing established design patterns.
In this first assignment we will be creating a front-end only Web app that will provide the user with a means for making and editing playlists. Note again, it is front-end only. So, once the page is loaded, we are storing all data in JavaScript variables and then saving to the browser's local storage. The app never talks to a database or back-end code of any sort. Should the user press the browser's Refresh button the full page will be reloaded using data from local storage. If you need to reset the data, just delete the Playlister app's entry in local storage.
Once you start the program you'll find that there are some exising Playlists that are loaded and partially edited. In fact, adding a new list works, so does changing the name of a song, as well as undoing that action and redoing that action. However, many other features do not work. In addition, there are many presentation things that need to be updated.
How are we using JSON
JSON stands for JavaScript Object Notation which like XML, is a Web standard for storing data. In fact, it is starting to replace XML in many respects. There are databases that store data in a JSON format, the same for local storage formats and data exchange between client and server many times uses JSON. JSON simply reflects the format of the data in JavaScript Objects, and has become a standard for the exchange of data. In this first assignment we will use a JSON file to load test data so that we can easily test all required functionality. In future HWs we'll use it for other things like for our database and for sending data between our front and back ends.
The Playlister App - Required Functionality
Learn how all the code I have provided you works before getting started. This is essential for software engineering. Going in using guesswork to make changes is no way to build high quality software. You need to map out all the pieces in your mind so that you know where to do your own code editing. To complete this assignment, do the following:
- Add a New Playlist - Note that when the app starts it loads three playlists from a JSON file, but there is no mechanism to add a new playlist. Add an add button per the UI screenshots at the bottom of this page such that when one clicks on the button it immediately adds a new playlist titled Untitled that contains no songs but is ready for editing.
- Duplicate a Playlist - Add a button to each playlist card for the user to duplicate that playlist (see the symbol below). When a playlist is duplicated, it is a deep copy, so the new playlist would start with all the same songs, but can then be edited independently. The name of the duplicate should be the name of the original concatendated with (Copy). Note that when a list is dupliate, the playlists should be ordered to reflect sorted order. Also note that immediately after being duplicated, the duplicate should be selected such that it can be edited.
- Add Song Years - Currently playlists let one view and change the title, artist, and YouTube id for each song, but note, if you look at the JSON data with the example data we're loading, each song also has the year it was released. Update the application such that one can also view and change the year for each song. This means you'l need to update the display of each song in the playlist as well as how it gets edited in the modal.
- Template the Song Cards - Note that when creating a dynamic front-end Web page, some HTML elements may only need to be created once, while others may need to be dynamically created and destroyed. For example, the status bar on the bottom of the application is always there, we can simply dynamically change its textual contents depending on which playlist is loaded. For such static elements we can put them as HTML templates inside index.html, which is a nice and neat way or organizing them. The playlist cards, on the other hand, will be added as new playlists are created or duplicated, and the song cards too. This means we don't know how many of these we'll need and we have to dynamically build them and add them to the UI, which is what the View does. But note, in this application I have provided 2 ways of doing this. One using templating (preferred) for the Playlist cards (see the PlaylistView's refreshPlaylistCards function), and one using raw JavaScript tree manpulation (not preferred) for the song cards (see the PlaylistView's refreshSongCards function). By templating we mean that a template prototye exists in index.html which is similar for each playlist card and so to add a new card we just clone that prototype and fill it in with details rather than having to do the ugly work of dynamically building DOM nodes. Change the way song cards are managed such that they also use templating, similar to the way the playlist cards do. This means you'll need to make sure when a new card is needed during a refresh, it is cloned from an existing component template (i.e. HTML) and filled in with the necessary details.
- Update a Song - Currently when the user double clicks on a song card it opens a modal and you can press cancel to close it, but pressing Confirm does nothing. Change this so that pressing Confirm will take whatever you entered in the modal's textfield (which must include year, of course), and the use that to update the selected song. Note, all such changes must be undoable/redoable - hitting ENTER should also fire event
- Remove a Song Verification Modal - When one presses the remove song button on one of the playlist song cards it will remove it, but it doesn't verify this first with the user. Update the application such that it asks that question of the user using a nice modal that swoops into view much like the one used for verifying if one should delete a playlist. Note, it should also be similarly styled per the UI screenshot at the bottom of this page.
- Undo/Redo - Note that Adding, Editing, and Removing a song should all be done via transactions, meaning they should all be integrated into the Undo/Redo system. Also note the redo button is never enabled so you'll need to fix this.
- Foolproof Design - it is important that you don't tempt users with features that are not usable. So, controls that are not usable should be either absent or visibly different (i.e. greyed out) and functionally disabled:
- Add List Button - if a list is in the process of being edited this button should be visibly and functionally disabled and only enabled if the edited list is first closed.
- Add Song Button - this button should only be enabled if a list is currently loaded and being edited.
- Undo/Redo Buttons - if there are no transactions to Undo, this button should be visibly and functionally disabled, the same goes for the Redo button.
- Close List - if a list is not loaded for editing the Close List button should be disabled.
- Add List Button - if a list is in the process of being edited this button should be visibly and functionally disabled and only enabled if the edited list is first closed.
Below are views of the user interface in action. Note that the green color denotes the currently selected list. The black list is currently moused over. Note the views below are the working app in action.
Figure 1 - Playlister workspace view
Figure 2 - Modal view for editing a song
Figure 3 - Modal view for verifying removing a song
There is obviously lots you'll have to do here starting with looking through a ton of my code to figure out what's going on here. Don't take the assignment lightly. When dealing with a large code base like this, everything takes time.
Finally
Remember, one of the most important principles for you to learn this semester is to plan, then do. You must learn how all of the code works and why it is arranged as is before starting, and you must plan your approach before coding. Don't just march off to the north pole in your underwear and hope for the best. Note that further discussions of these requirements will be given during lecture.
Handin Instructions
When you are done, zip up the entire 316-HW1-Playlister directory and submit that single ZIP file via Brightspace. Note, it must be a .zip file, not a .rar file. Do not include the node_modules directory in your zipped up submission. Note, if you include that directory you will lose points for your submission.
Grading Appointments
Note that grades for this assignment will mostly be based on program performance and grading will only be done by appointment with each student's prescribed Teaching Assistant. This part of your grade will be based on how well your program performs specific required tasks. Additionally, points will be deducted if GitHub is not used properly, meaning incrementally over the course of working on the project for each bit of working implementation. Make sure you use GitHub properly from start to finish, committing your progress as you go with each assignment.