AJAX - Due Friday, April 20th by 11pm
Overview
Goals / Topics Covered
You'll be using the following concepts:
- XMLHttpRequest
- sending back json from Express
Description
Convert the course review site from a previous homework to a "single page app". Use AJAX POSTs and GETs instead of regular form submissions to filter and add course reviews
You will:
- Implement routes to create an API for retrieving reviews and adding new ones
- Use JavaScript to trigger background requests to the API from the form submit buttons
Use the following resources as reference:
Check out the video below to see how the site will work. Pay attention to:
- the button presses
- the changes in the ui
- …and the network tab
- notice that there are no page refreshes!
Submission Process
You will be given access to a private repository on GitHub. The final version of your assignment should be in GitHub
- Push your changes to the homework repository on GitHub.
- Commits later than that date will be handled on a case-by-case basis.
Make at Least 3 Commits
- Commit multiple times throughout your development process.
- Make at least 3 separate commits
Code Structure:
You should first create an express application that will be served on port 3000
The structure of the directory you're given looks like this:
package.json
src
└── coursez
├── app.js
├── db.js
├── public
│ ├── index.html // the 'single' page in your single page web app
│ ├── js
│ │ └── main.js // write your client side JavaScript here
│ └── stylesheets
│ └── style.css
└── views
Note that this will be implemented as a single page web app. This means that to implement these features:
- create routes that send back JSON (essentially create an API)
- utilize the API by writing client side JavaScript that:
- constructs an http request by retrieving the values of form elements
- requests data from url constructed in the background (AJAX)
- parses the result of the background request
- modifies the DOM appropriately
Some of This Project is Already Built for You!
- Server side code
- database setup (a mongoose model, database connection, etc.) is provided through
db.js
- a partially implemented Express application is in
app.js
- it has basic setup for body parsing, static files, etc.
- it has stubs for route handlers, but the implementations are left
- database setup (a mongoose model, database connection, etc.) is provided through
- Client side code
- there are static files present in
public
- the html (
index.html
) and css (style.css
) are already built - but the client side JavaScript is not implemented (
main.js
), so you'll have to write all of your client side code there
- there are static files present in
Fetching and Filtering:
- Finish the route,
GET /api/messages
, which returns all of the existing reviews in the database- This route will support some of the same query string parameters as the course review assignment: year and semester
- It should return JSON list of review objects. For example, `GET /api/messages?year=2018
could return:
[ { "name":"Course 1", ... }, { "name":"Course 2", ... } ]
- Note that the model only contains these properties (which are less than the previous assignment):
name
- the course namesemester
- the course semesteryear
- the year the course was offeredreview
- the text of the course review
- To test, add some data into your database manually using the commandline mongo client using the properties supplied above
- enter the url
http://localhost:3000/api/messages
in your browser; you should get JSON back… with the JSON containing the reviews that you entered through the commandline
- Add some JavaScript to
src/public/js/main.js
so that once the page loads:- a background request is made to the the api url above using
XMLHttpRequest
- no query string parameters should be present, so all of the reviews should be present in the response
- parse the response to get a collection of reviews
- add the reviews to the
tbody
element of thetable
as rows and table data (tr
andtd
) - use
document.createElement
to do this (avoid usinginnerHTML
) - at the end of this task, on initial page load, your application will make a background call to load all of the reviews in the database, so the page should have both the form and a table populated with reviews
- a background request is made to the the api url above using
- Using JavaScript in
main.js
, modify the form so that when the button is pressed:- the regular form button press event isn't triggered (use
preventDefault
) - instead, the values in the filter form field are retrieved from their elements and are used to construct the url to be requested (use the
.value
property of the form element) - construct the url by using the base path,
/api/messages
and add a query string by concatenatingsemester
andyear
to it - make a background request to the url you construct using
XMLHttpRequest
- when the JSON is returned, it should be parsed into a list of objects representing reviews
- use those review objects to replace the contents of the table on the page (for example, you could remove all the children in
tbody
usingparentElement.removeChild(childElementToRemove)
- filtering with a blank field removes that field from the filter (so if semester were empty string, all semesters are allowed)
- the regular form button press event isn't triggered (use
Adding New Reviews
- In the route,
POST /api/message
, create a new review- it should give back a JSON object as the response
- it should send back the object inserted, if successful
- otherwise, send back an object with a key called error… with a value containing an error message
- The normal behavior of forms will need to be modified so that when the add button is pressed:
- the regular form button press event isn't triggered (use
preventDefault
) - … and instead, the values in the add form are retrieved
- a background request is made to the url
- remember to set content type:
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
- in
res.send
, make sure to add the form data as name value pairs:"name1=value1&name2=value2&nameN=valueN"
- remember to set content type:
- when a response is retrieved, repopulate the table so that the new review is added
- if there was a filter set before adding, then clear the filter to show all reviews, including the newly added one
- the regular form button press event isn't triggered (use
See the movie from earlier in the instructions to check out an example of adding a review (pay close attention to the network tab showing the requests).