$30
Objective:
Build upon the foundation established in Assignment 2 by providing new routes / views to support adding new people and uploading images.
NOTE: If you are unable to start this assignment because Assignment 2 was incomplete - email your professor for a clean version of the Assignment 2 files to start from (effectively removing any custom CSS or text added to your solution).
Specification:
For this assignment, we will be enhancing the functionality of Assignment 2 to include new routes & logic to handle file uploads and add people. We will also add new routes & functionality to execute more focused queries for data (ie: fetch a person by id, all cars by a make or vin number, etc)
Part 1: Adding / Updating Static (.html) Files & Directories
Step 1: Modifying home.html & about.html
Open the home.html file from within the "views" folder
Add the following two entries to the <ul class="nav navbar-nav"> element:<li><a href="/people/add">Add People</a></li> o <li><a href="/pictures/add">Add Picture</a></li>
Add the following entry as the first child element of the <ul class="nav navbar-nav navbar-right"> element<li><a href="/pictures">Pictures</a></li>
Your "Home" page should now have a menu bar that looks like the following:
Update your "About" page with the same changes. When complete, it should look like the following:
Step 2: Adding new routes in server.js to support the new views
Inside your server.js file add the following routes (HINT: do not forget __dirname & path.join):
GET /people/addThis route simply sends the file "/views/addPeople.html "
GET /images/addThis route simply sends the file "/views/addImage.html
Step 3: Adding new file 1: addPeople.html
Create a new file in your "views" directory called "addPeople.html" and open it for editing
Copy the contents of "home.html" and paste it in as a starting point.
Ensure that the "Add People" item in the <ul class="nav navbar-nav"> …</ul> element is the only <li> with the class "active" (this will make sure the correct navigation element is "highlighted")
Remove all html code inside the <div class="row"> … </div>
Inside the (now empty) <div class="row"> … </div> element, use the html from the sample solution
( https://secret-brook-17817.herokuapp.com/people/add) to reconstruct the "Add People" form (HINT: You can right-click the page to "view source" - the html you want is within the <div class="row"> …</div> element)
Step 4: Adding new file 2: addImage.html
Create a new file in your "views" directory called "addImage.html" and open it for editing
Copy the contents of "home.html" and paste it in as a starting point.
Ensure that the "Add Image" item in the <ul class="nav navbar-nav"> …</ul> element is the only <li> with the class "active" (this will make sure the correct navigation element is "highlighted")
Remove all html code inside the <div class="row"> … </div>
Inside the (now empty) <div class="row"> … </div> element, use the html from the sample solution
( https://secret-brook-17817.herokuapp.com/pictures/add) to reconstruct the "Add Image" form (HINT: You can right-click the page to "view source" - the html you want is within the <div class="row"> …</div> element)
Step 5: Adding a home for the uploaded Images
Create a new folder in your "public" folder called "pictures"
Within the newly created "pictures" folder, create an "uploaded" folder
Part 2: Adding Routes / Middleware to Support Image Uploads
Step 1: Adding multer
Use npm to install the "multer" module
Inside your server.js file "require" the "multer" module as "multer"
Define a "storage" variable using "multer.diskStorage" with the following options (HINT: see "Step 5: (server) Setup…" in the week 5 course notes for additional information)destination "./public/pictures/uploaded"
filename function (req, file, cb) { cb(null, Date.now() + path.extname(file.originalname));
}
Define an "upload" variable as multer({ storage: storage });
Step 2: Adding the "Post" route
Add the following route:
o POST /pictures/add
This route uses the middleware: upload.single("pictureFile")
When accessed, this route will redirect to "/pictures" (defined below)
Step 3: Adding "Get" route / using the "fs" module
Before we can add the below route, we must include the "fs" module in our server.js file (previously only in our data-service.js module)
Next, Add the following route:
o GET /pictures
This route will return a JSON formatted string (res.json()) consisting of a single "pictures" property, which contains the contents of the "./public/pictures/uploaded" directory as an array, ie { "images": ["1518109363742.jpg", "1518109363743.jpg"] }. HINT: You can make use of the fs.readdir method, as outlined in this example from code-maven.com
Step 4: Verify your Solution
At this point, you should now be able to upload images using the "/pictures/add" route and see the full file listing on the "/pictures" route in the format: { "pictures": ["1518109363742.jpg", "1518109363743.jpg"] } .
Part 3: Adding Routes / Middleware to Support Adding People
Step 1: Adding body-parser
Use npm to install the "body-parser" module
Inside your server.js file "require" the "body-parser" module as "bodyParser"
Add the bodyParser.urlencoded({ extended: true }) middleware (using app.use())
Step 2: Adding "Post" route
Add the following route:
o POST /people/add
This route makes a call to the (promise-driven) addPeople(peopleData) function from your dataservice.js module (function to be defined below). It will provide req.body as the parameter, ie "data.addPeople(req.body)".
When the addPeople function resolves successfully, redirect to the "/people" route. Here we can verify that the new person was added
Step 3: Adding "addPeople" function within data-service.js
Create the function "addPeople(peopleData)" within data-service.js according to the following specification:
(HINT: do not forget to add it to module.exports) o Like all functions within data-service.js, this function must return a Promise
Explicitly set the id property of peopleData to be the length of the "people" array plus one (1). This will have the effect of setting the first new person’s id to 1001, and so on.
Push the updated peopleData object into the "people" array and resolve the promise.
Step 4: Verify your Solution
At this point, you should now be able to add new people using the "/people/add" route and see the full people listing on the "/people" route.
Part 4: Adding New Routes & queries
A) "People"
Step 1: Update the "/people" route
In addition to providing all of the “people”, this route must now also support the following optional filters (via the query string) o /people?vin=value
return a JSON string consisting of all people where value is equal to a certain vin number (hint: use “3G5DB03E13S795969” to get “Catriona Farherty”)- this can be accomplished by calling the getPeopleByVin(vin) function of your data-service (defined below)
o /people
return a JSON string consisting of all people without any filter (We have already made this in assignment 2)
Step 2: Add the "/person/value" route
This route will return a JSON formatted string containing the person whose id matches the value. For example, once the assignment is complete, localhost:8080/person/61 would return the person: Catriona Farherty - - this can be accomplished by calling the getPeopleById (id) function of your dataservice (defined below).
B) "Cars"
Step 1: Update the "/cars" route
In addition to providing all of the “cars”, this route must now also support the following optional filters (via the query string) o /cars?vin=value
return a JSON string consisting of all cars where value is equal to a certain vin number(hint: use “3G5DB03E13S795969” to get “1992 Infiniti Q”)- this can be accomplished by calling the getCarsByVin(vin) function of your data-service (defined below)
/cars?make=value
return a JSON string consisting of all cars where value is equal to a car’s make (hint:
use “Ford” to get a list of all the ford cars)- this can be accomplished by calling the getCarsByMake(make) function of your data-service (defined below)
/cars?year=value
return a JSON string consisting of all cars where value is equal to a car’s year (hint: use “1997” to get a list of all the cars made in 1997)- this can be accomplished by calling the getCarsByYear(year) function of your data-service (defined below)
/cars
return a JSON string consisting of all cars without any filter (We have already made this in assignment 2)
Part 5: Updating "data-service.js" to support the new "People" and "Cars" routes
Note: All of the below functions must return a promise (continuing with the pattern from the rest of the dataservice.js module)
Step 1: Add the getPeopleByVin(Vin) Function
This function will provide an array of "people" objects whose vin property matches the vin parameter, use the resolve method to return the array.
If for some reason, the length of the array is 0 (no results returned), this function must invoke the reject method and pass a meaningful message, ie: "no results returned".
Step 2: Add the getCarsByVin(vin) Function
This function will provide an array of "cars" objects whose vin property matches the vin parameter, use the resolve method to return the array.
If for some reason, the length of the array is 0 (no results returned), this function must invoke the reject method and pass a meaningful message, ie: "no results returned".
Step 3: Add the getCarsByMake(make) Function
This function will provide an array of "cars" objects whose make property matches the make parameter, use the resolve method to return the array.
If for some reason, the length of the array is 0 (no results returned), this function must invoke the reject method and pass a meaningful message, ie: "no results returned".
Step 4: Add the getCarsByYear(year) Function
This function will provide an array of "cars" objects whose year property matches the year parameter, use the resolve method to return the array.
If for some reason, the length of the array is 0 (no results returned), this function must invoke the reject method and pass a meaningful message, ie: "no results returned".
Step 5: Add the getPeopleById(id) Function
This function will provide a single “person” object whose id property matches the id parameter (ie: if id is 261 then the "people" object returned will be "Coleen Challender") using the resolve method of the returned promise.
If for some reason, the length of the array is 0 (no results returned), this function must invoke the reject method and pass a meaningful message, ie: "no results returned".
Part 6: Pushing to Heroku
Once you are satisfied with your application, deploy it to Heroku:
Ensure that you have checked in your latest code using git (from within Visual Studio Code)
Open the integrated terminal in Visual Studio Code
Log in to your Heroku account using the command heroku login
Create a new app on Heroku using the command heroku create
Push your code to Heroku using the command git push heroku master
IMPORTANT NOTE: Since we are using an "unverified" free account on Heroku, we are limited to only 5 apps, so if you have been experimenting on Heroku and have created 5 apps already, you must delete one (or verify your account with a credit card). Once you have received a grade for Assignment 1, it is safe to delete this app (login to the Heroku website, click on your app and then click the Delete app… button under "Settings").
Testing: Sample Solution
To see a completed version of this app running, visit: https://secret-brook-17817.herokuapp.com
Please note: This solution is visible to ALL students and professors at Seneca College. It is your responsibility as a student of the college not to post inappropriate content / images to the shared solution. It is meant purely as an exemplar and any misuse will not be tolerated.