CPSC 2600 Midterm Exam Overview: In this exercise, you'll create a basic web application that displays a list of links to pictures of dogs, and a single randomly-chosen image from that list. See the...

i am not able to select folder to attach my files


CPSC 2600 Midterm Exam Overview: In this exercise, you'll create a basic web application that displays a list of links to pictures of dogs, and a single randomly-chosen image from that list. See the demo video for a demonstration of how the final application should work. I've given you some starter files with the following: - The index.html file that I would like you to use for the front end. You don’t have to do anything to this file. I've included a script tag linking to the Axios library, but you’re not obligated to use it. - A script.js file with some pre-written code that creates a list of links to dog images. You don't even have to do this part! - A folder called resources that is full of dog images. - A CSV file called imageNames.csv with the file names of the dog images in the folder. I'll walk you through a list of things to do to get the app working, but here's a summary of what your code should eventually do: - Read the file names from the CSV file; nothing else in the application should work until this asynchronous process has completed. In particular, I'd like you to use a promise- based interface for this. I'll show you how to do this in a moment! - Expose one or more routes, implemented in Express, that allow one to make GET requests for the following: o an array of all file names; o a single, randomly-chosen file name. Bonus +1: use a single route with a URL query parameter to toggle between the above two outcomes. - Allow each image to be accessed at endpoints of the form /resources/ - Implement the functionality on the front end to display a random dog image (from the resources folder) every time the page is reloaded. Task 1: Reading and Parsing the CSV File Rather than writing a program for parsing CSV files, we're going to use an NPM module called csv-parser to help us. Start by using NPM to install two new packages: csv-parser and strip-bom-stream. Create a new file /data/loadFileNames.js. Also place imageNames.csv in the data folder. In loadFileNames.js, require these modules: const csvParser = require('csv-parser'); const stripBom = require('strip-bom-stream'); const fs = require('fs'); const path = require('path'); The above modules are doing the following: - csv-parser o This package will allow us to pass the contents of CSV file into a stream that will convert that file data into JavaScript objects; - strip-bom-stream o This module will strip the byte order marker from the start of CSV files, which will be required to prevent the row objects created by CSV-Parser from breaking; - fs o This is the Node file system module that will allow us to create a read stream and read the contents of our CSV files. - path o Node module for normalizing file system paths. Next, we're going to create a function that takes the file name as a parameter and returns a promise; the promise will resolve when all the rows of the CSV file have been read, with the array of file names as its value. const getRows = fileName=>new Promise((resolve,reject)=>{ // code for reading and parsing the CSV file will go here. }); As you can see, the above function is returning a new promise; inside the function that the Promise constructor receives as a parameter, add the following: // array of file names let names = []; fs.createReadStream(path.join(__dirname, fileName)) // read file .pipe(stripBom()) // strip out byte order mark before sending to csv parser .pipe(csvParser()) // parse the CSV file .on('data', row => { // get current row of CSV file. This code will be run for each row. // push the row to the array of file names. names.push(row['File Name']); // the column header name is used to access the value in the row (useful when we have more than one column in the CSV file) }) .on('end', () => { // once we reach the end of the file, resolve the promise with the file names as the value. resolve(names); }) .on('error', error=>{ // if there's an error, reject the promise with the error object. reject(error); }); Finally, add the above function to your exports so that you can require it in other files: module.exports = getRows; The fs.createReadStream function creates a readable stream that allows us to pull chunks of data from the given file and process them one by one. Then we're using pipe functions to pass these chunks of data to other streams for further processing. Since the above function returns a promise, you can use it like this: getRows("imageNames.csv") .then(fileNamesArray=>{ // use the file names array as needed. }) .catch(error=>{ // handle errors }); // Code written down here is not guaranteed to have access to the file names array due to asynchronous, non-blocking nature of file IO. Task 2: API Your next task is to use Express to allow a user to make GET requests to your server-side application to do the following: - Get the full array of image file names. Use the endpoint "/images" for this route, since this is what I'm using in my front-end code. - Get one randomly-chosen image file name. o As mentioned, you get the bonus mark if you can do both things with the same route with a query parameter. - If a user tries to get this data before the CSV file has been fully read and parsed, they're going to have a problem. You must write your code to make sure this never happens! There are several ways to do this, and I'm not concerned about which way you choose. One thing that might be helpful (although not necessary) is using app.locals to store variables such that they can be used anywhere in the application. If you're in a file that doesn't have access to the app object, you can access it using the request object req.app.locals. Task 3: Front End I've already written the code for displaying a full list of all file names with hyperlinks to the actual images. If your API in task 2 is working properly, you should see this list appearing in your application. (If it isn't appearing, you may have to go back to task 2 and figure out the problem.) All you have to do is implement the functionality for pulling a random image from the server and displaying it in the

tag that is already in index.html. Hand In If you haven't done so already, make sure the application is set to auto-restart on port 8080 by doing the following: - Use NPM to install nodemon - Add a script to package.json that runs the application with nodemon: "dev": "nodemon app.js" (or replace "app.js" with whatever your Express application is called.) Delete the .c9 and node_module folders. Make sure your project has the package.json file with all necessary dependencies and the dev script. After importing your project, I should be able to get it working using the following terminal commands: npm install npm run dev Download your project, extract it, rename it to 2600midterm-firstname-lastname (with your own first and last name), create a zip archive (not some other kind of archive like rar or 7z) and hand it in to D2L. Please do the above in the specified order, since it makes a difference to me when I'm extracting the files. Grading - [1] getRows function; - [2] asynchronous functionality implemented correctly for getting data from CSV file and sending to client; - [2] Handing GET request for array of file names and random file name; - [1] Image files publicly accessible - [2] Front end with new random image on reload Total: 8 Note that up to -2 may be deducted for disorganized files and code, incorrect hand in procedure, poor code formatting and style, etc. Ask me if in doubt. Late submissions will not be graded.
Oct 17, 2021
SOLUTION.PDF

Get Answer To This Question

Related Questions & Answers

More Questions »

Submit New Assignment

Copy and Paste Your Assignment Here