COMP 2406 AB Fall 2019 Tutorials 8
Objectives
Create an Express app that uses MongoDB for data storage
Practice querying MongoDB from within an Express app
Expectations
To receive full grades for this tutorial, you must complete problems 12 and make
progress on problem 3 before the deadline. If you do not have time to complete the required problems, you should attempt them afterward for your own benefit. Remember to use the available resources w3schools, Node.jsExpress documentation, lecture notesrecordingscode, etc. if you are struggling to complete the problems.
Grading Scheme
Tutorials account for 10 of your course grade. Each tutorial will be graded out of 3. You will receive 13 if you do not make enough progress on the problems or cannot explain your solutions to the TA. You will receive 23 for completing almost all the required problems and can explain your solutions to a TA. You will receive 33 if you complete all the required problems and can explain your solutions to the TA.
If you do not complete all the tutorial work by the end of the tutorial, you may demonstrate your work within the first 30 minutes at the following weeks tutorial. For example, you can demonstrate tutorial 1 at tutorial 2, tutorial 2 at tutorial 3, etc. There will be no penalty for work demonstrated at the following tutorial. However, this will be your last chance to get marks for the tutorial work: you cannot demonstrate tutorial 1 in the session for tutorial 3, and so on.
1
Problem Background
The goal of this tutorial will be to provide a card search service that allows the user to specify a filter and have the server return cards matching that filter. This tutorial will continue to work with the dataset from tutorial 7. You do not, however, need to have completed tutorial 7 in order to start this tutorial. A summary of the fields available within each object of the dataset is provided at the end of this document. Download the T08BaseCode.zip file from cuLearn to get started. This zip file contains the following files:
1. databaseinitializer.js: Run this file while the Mongo daemon is running and it will create a database called t8 with a collection called cards that contains all of the cards from the dataset.
2. server.js: This file contains an Express app that provides some base functionality for you. When you run this file, it will connect to the Mongo database and initialize a variable called db representing the t8 database. You can use this variable to query the database throughout your app. The server will also serve a default index page using Pug in response to GET requests for the route , and respond to GET requests for the parameterized URL cards:cardID when given a valid ID from the database.
3. viewsindex.pug: The template file used to render the default index page. You can add any additional elements that are necessary to this file as you progress through the tutorial.
4. viewscard.pug: The template file used for rendering single card pages.
Problem 1 Finishing the Index Page
Run the server.js file and load the index page. The class and rarity dropdown menus do not currently have any values contained within them. Add code so that each of the dropdown menus has a complete list of all classesrarities within the dataset. To find all of the classesrarities, you can use the db.collection.distinctfieldName method within MongoDB. For example, db.cards.distinctcardClass will return an array of the unique card classes within the database. You can add the values manually into the dropdown menu or automate the process, so the information is loaded from the database at runtime. One way you could loading at runtime is to have your server query the database for the unique classesrarities and pass that information to the index.pug template when it is rendered.
Problem 2 Querying for ClassRarity
The next step will be to allow the client to use the index page to query cards based on class andor rarity. One way to do this is to add clientside Javascript capable of
2
querying the server and performing page updates. An alternative approach would be to modify the index page to have a form that would allow the client to submit a request to the server using the Refresh button and load an entirely new page containing the results. You are free to take either approach, but only the clientside Javascript approach will be explained in more detail here.
Start by creating a clientside Javascript file and adding a reference to that file into the index page template file. Update your server so that the client Javascript can be loaded successfully. The clientside Javascript should add a click handler to the refresh button. When the refresh button is clicked, you can create an XMLHttpRequest including the classrarity information from the page and send it to the server. The server can respond with a list of matching cards.
To facilitate this, add a route on your server to handle GET requests to the URL cards. Add code to handle query parameters so that card class and rarity values can be specified in the request. Add code into the route handler to build a query document using the query parameters e.g., card class and rarity, query the database for matching cards, and send a response to the client containing the matching cards.
There are multiple ways you can send the response back to the client. First, you could send JSON data to the client and have the clientside Javascript update the HTML on the page like earlier tutorials. An alternative approach is to render a partial page using Pug and send that HTML to the client directly. Create a new Pug template file that will accept an array of card objects as input. This template should produce a partial page e.g., no htmlheadbody elements that contains a list of the matching cards. Each card entry should be a link to that specific card page use the id field from the database and the text of the link should be the card name. When the clientside Javascript receives this HTML in response to its XMLHttpRequest, it can update the inner HTML of the results div on the page.
Test out your code before proceeding. For reference, the correct card name results for classMAGE and rarityLEGENDARY are: Rhonin, Stargazer Luna, Inkmaster Solia, Archmage Antonidas, Toki, TimeTinker, Archmage Arugal, Flame Leviathan, Sindragosa, Dragoncaller Alanna, Anomalus, Pyros, and Pyros. You can also click each card you get in your result list to ensure the values of the card match the search query.
Problem 3 Adding Other Query Parameters
Now add support for the remainder of the query parameters:
1. Min AttackHealth: These are integer values. A card should match if its
attackhealth property is greater than or equal to the query parameter value.
3
2. Max AttackHealth: These are integer values. A card should match if its attackhealth property is less than or equal to the query parameter value.
3. NameArtist: These are string values. A card should match if the card nameartist value contains the given value. Additionally, you should ensure that the search is done in a caseinsensitive matter. You can use a regex query operator in MongoDB to perform a string search of these fields.
It will likely be easiest to add support for the integer parameters first. Note that since a card must match all specified query parameters, you can use a single and query with an array containing an entry for each query parameter that has been specified in the request.
Summary of Fields in Card Documents:
Each card in the dataset has the following field names:
1. id: the unique ID created by MongoDB when the card was inserted
2. artist: a string representing the name of the artists that created the card art
3. name:astringrepresentingthenameofthecard
4. cardClass: a string representing the class of player that can use the card
5. rarity:astringrepresentingtherarityofthecard
6. attack: an integer representing the attack value of the card
7. health:anintegerrepresentingthehealthvalueofthecard
Additional fields have been removed from the dataset, as they are not necessary for this tutorial.
4