Learning objectives:
- Learn Express router
- Practise using promises
- Practise server side rendering
When complete, your application might look like this:
-
After cloning this repo, install dependencies with
npm install, and start the dev server withnpm run devMore about getting started
- To start the server:
npm start - To debug the server (and have it reload with Nodemon after changes):
npm run dev - To run the tests:
npm test
- To start the server:
Important tips for completing the challenge
- The order of routes is important. The first one that matches will be used. So if you have a
/:idroute before an/editroute, a request to/editwill choose the/:idroute and the value ofreq.params.idwill be"edit". - There can only be one server response (e.g.
res.send()orres.render()) per request. If you have multiple potential responses (like a success and an error response) make sure to write your logic so that the route responds appropriately. - Make sure to
JSON.parseandJSON.stringifywhen reading/writing JSON data. - Don't forget to handle errors when your promises fail using
.catch(...) - When in doubt check the node
fs/promisesdocumentation
-
Let's get our server running with a default route
More about the server
- In the
server/server.js, add an HTTP GET root route (/). For now, let's just send the word 'Pupparazzi' - Start the server and go to http://localhost:3000 to see if we are winning
Now that we have a root route, let's use it to see some puppies.
- In the
-
As a user, I want to see some puppies, so that I can say "awwww"
More about displaying puppies
In our server file, change the GET
/route function. We will use this route to:- read the puppies from our
data.jsonfile (which lives in the sibling./datadirectory) usingreadFilefrom'node:fs/promises'. Don't forget to parse the data into a JavaScript object - render the puppies using the
homeview (that has already been created) and your puppies data
If your page renders, but there are no puppies:
- check what data the view is expecting to receive
console.logthe view data object you are passing to the render and make sure this matches what the view is expecting
You should now have the puppies rendering on the
/page. If you click on the picture however, the link it takes you to is broken (because we haven't written it yet). Let's fix that now. - read the puppies from our
-
As a user, I want to click on a puppy and see their name, breed, and who their owner is
More about puppy pages
- Take note of the url you are sent to (perhaps
/puppies/1) - Create a
routes.jsfile in the main repo directory - this will store all of our routes requireExpress in yourroutes.jsfile and create a router. Also, don't forget to export the routerrequireanduseour newly createdroutes.jsfile in ourserver. We'll use the string/puppiesto define the prefix path for our router. Note that theuseline of code should come after your server configuration and handlebars configuration- Create a GET route in your
routes.jsto render a particular puppy. The route should contain theidas a parameter so you can access it viareq.params.id(so perhaps/:id) - Similarly to the
/route inserver.js, it should read the puppies from our JSON file, but this time, we will need to use the id to find only the selected puppy from thepuppiesarray - Render the puppy. As before, the
detailsview has already been created for you
- Take note of the url you are sent to (perhaps
-
As a user, I want to be able to update the puppy's name, breed, and owner
More about pupdates
For this, we are going to need GET a form to edit/update the puppy information. This form also needs to POST the updated information from the form to the server. Hence, we are going to need two routes this time (don't panic!)
For the GET
/puppies/:id/editroute:- Loop through our JSON file and find the puppy that we want to edit (don't forget that id as a parameter)
- Render the form using the
editview and the puppy data that we want to edit
For the POST
/puppies/:id/editroute:- Create an object of the updated puppy data from the request body
- Read in the JSON file and locate the puppy we are going to update
- Update the puppy in the array
- Write the entire array back into the JSON file (with
fsPromises.writeFile) - Redirect to the GET
/puppies/:idroute
If all goes well, you should be able to update the puppy information. If that isn't happening, undoing the changes you've made to the JSON file might come in handy.
More about stretch challenges
If you've reached this point, congratulations! As a stretch, you might like to do the following:
- Refactor the
readFileandwriteFilecalls into a separate file (separation of concerns)- As these return promises to begin with, you will need to write functions around them which also return promises
- Write some tests using
jestandsupertest
- Add a new view and route that includes a form which lets the user add a new puppy
