Lookup

Searching a database for useful information using the Mongo shell is difficult at best and requires knowing the MQL language. In this assignment, you'll create a web interface somewhat similar to the IMDB but pulling data from the WMDB.

In this assignment, you'll demonstrate command of the basics of Node/Express apps connecting to a MongoDB database (the WMDB). This is our first real web-database application!

  • Processing parameterized GET requests
  • Connecting to a database and making queries from Python
  • Combining dynamic data with static templates to produce rendered pages
  • Handling different routes
  • Dynamically creating hyperlinks
  • Using forms to get information from the user

Solution

To see an example of what you might build, you can look at

my reference solution

Alternatively, if there is any trouble with the previous link, you can try this:

lookup solution (flask version)

Note that the URLs on the deployed solutions have a prefix like /lookup/ or cs304lookup/; you should not do that.

Please don't feel that you have to present exactly the same interface that I do. I'm sure you can think of something more interesting, creative, or beautiful. Nevertheless, it exhibits the functionality I want.

Web Interface

The app will support these important URLs:

  • To display the movie with TT = 456, the URL will be /tt/456
  • To display the person with NM = 123, the URL will be /nm/123
  • To look up movies or people with a fragment of the name or title:

/search/?term=text&kind=movie/person

where term is the term (word) to search for, and movie/person indicates what kind of thing to search for.

In addition, the main page should have links to an example of a person and an example of a movie. Don't just use my example; use you and your partner's favorite!

The Lookup Routes

You have to implement four routes:

  • something that displays a search form. I suggest using the / route for that.
  • a /search/ route that processes the submitted search forms
  • a /nm/<person_id_number> route that shows the detail page for that particular person.
  • a /tt/<movie_id_number> route that shows the detail page for that particular movie.

You will not need to use POST in this assignment, since we are not updating the database, and POST is for updates. All routes will use GET.

Order

I strongly suggest that you proceed like this:

  1. Implement a /nm/<person_id_number> route that shows the detail page for that particular person. Skip the links to movies for now.
  2. Test it by visiting localhost:8080/nm/123, substituting whatever port you are using. Do you see George Clooney's page?
  3. Implement a /tt/<movie_id_number> route that shows the detail page for that particular movie. Skip displaying the cast for now. Test it with http://localhost:8080/tt/1454468 Do you see Gravity?
  4. Improve that page by adding hyperlinks to the cast for Gravity. Those will be links to /nm/ routes, but those work now.
  5. Improve the person detail page by adding links to their movies.
  6. Test that

Okay, now you're ready to display the form.

  1. Implement a dummy handler for processing a form. It should just print the two values from the form to the console and return a dummy result like You submitted ${term} and ${kind}
  2. Create a partial file that has the form. Make sure the ACTION of the form is the URL for the dummy handler you just created.
  3. Include the partial file on the main page
  4. Implement a home route that renders the main page.
  5. Test that the form submits and has the information you need.

Finally, you're ready to process the form, which is last.

  1. The form submission handler gets the two pieces of information from req.query
  2. It makes the appropriate query, getting a list of results.
  3. Print the result list to the console.
  4. Test that code.
  5. Add a conditional in the handler that looks at how long the list is.
    • if the list is length zero, inform the user
    • if the list is length one, redirect them to the appropriate detail page
    • if the list is longer than one, print a list of hyperlinks to the various detail pages.

Movie Detail Page

The movie detail page must give the title of the movie in an H1 element with a class of title. It must have a paragraph with the title and release year. Then a list of the cast, with each name hyperlinked to the person's page.

Person Detail Page

The person page must give the person's name in an H1 element with a class of person. It must also have a paragraph saying the name of the student (staff member) who added that person, and when the WMDB person was born. Then, it must have a list of the actor's movies (if any), each hyperlinked to the movie page.

Note that the person page is a little more complicated than the movie page. You might start with the movie page.

Feel free to substitute the word person wherever I said actor, since the people in the person table are not always actors, though our focus in this assignment is on actors, since we are listing the cast of a movie.

Depending on how you do your coding, the detail page for a person can end up missing a lot of data, particularly if either they have no films (maybe they are a director) or their addedby field is null (it shouldn't be, but it happens sometimes). Your coding should handle those situations and at least give the person's name and birthdate (if any).

Errors

If a person is not found, the page must say:

Sorry, no person with that ID is in the database

Similarly, if a movie is not found, the page must say:

Sorry, no movie with that ID is in the database

Multiple Matches

You should get the earlier stuff working first. Once it's working, add the partial your other pages (so that it appears on every page).

The handler must allow people to search by part of a person's name or part of a movie title. There are then three cases:

  • No matches; report that situation, as specified above.
  • Exactly one match; redirect to the detail page for that person or movie
  • Multiple matches; render a page that lists all the matches, as hyperlinks to the detail page for that person/movie.

Strict API

Because I'll be doing semi-automated testing of your scripts, they need to have precise names and interfaces. Please use the URLs that I described above.

This strict API won't affect your coding much, if at all. Please, be creative in your appearance and the internals of your web app, not in the interface.

I'll be testing your code with URLs like these:

/
/nm/123
/search/?term=clooney&kind=person
/search/?term=george&kind=person
/tt/1454468
/tt/666
/search/?term=sally&kind=movie
/search/?term=harry&kind=movie

If you don't understand those URLs or what they should produce, please talk to me. You can also try them in my reference solution, above.

Getting Started

I suggest starting with the people app. You can easily copy it to your apps folder like this:

cd ~/cs304/apps/
cp -rd ~cs304node/apps/people lookup
cd lookup

Testing Your Code

You should, of course, test your code to make sure that the kinds of URLs listed above work.

Hints

  • Put a place on the main page to render error messages and supply that value from the res.render function. If you use a conditional and supply null or false when there's no error, there won't even be an empty container.
  • Formatting dates doesn't have to be hard. At first, just report the YYYY-MM-DD pattern that the database has. When you're ready, you can use the new Date(string) constructor to convert the date string into a date object. Then you can format it in a variety of ways, using the methods of the date object.

Advice

Everyone has their own habits for programming assignments, but here is some advice that you may find helpful. I found it useful to remind myself of these as I was coding the solution!

  • Test your queries using the Mongo client or a cut-down script like we did with the Queries assignment, where it'll be easier see what kinds of results you'll get.
  • Build in small increments. Don't sit down and code a complete solution right away. Code the smallest thing that you can test and then test it.
  • Test often. As soon as you build a small chunk of the solution, test it and see if it works. Try to leave things in working order before you turn to other homework assignments.
  • Look at the source of your HTML pages (the output of your scripts). Bugs there can be hard to track down if you're just looking at your JavaScript code.
  • Using the HTML validator on the rendered source (use "view source" in your browser) sometimes helps
  • Document as you go, so you'll know what works and what assumptions you're making.
  • Take breaks. If you run into programming troubles that seem intractable, don't beat your head against it for hours. Take a break and come at it again when you're fresh. Sometimes that's all it takes to figure the problem out. We've all had that experience, I think.

Improved User Experience

As an incentive to spend a little time thinking about a beautiful as well as functional interface, you can earn up to 10 additional points for your interface. That's a pure judgment call on my part, based on nominations from the graders.

How you'll be graded

My policy for this programming assignment (and most programming assignments) is:

  • 70 percent for functionality: does it work? do all the features work? all test cases passed?
  • 10 percent for modularity and coding style
  • 10 percent for documentation
  • 10 percent for efficiency and other stuff

Specifically, I will look for:

  • No global variables (constants are ok). This includes the database connection.
  • Good modularity, function/variable names and parameter passing
  • Good documentation
  • Reasonable programming style. Lines shouldn't go beyond 80 characters

Please don't forget all the good programming techniques that you've learned in earlier classes. Look for appropriate abstractions and useful modules to reduce the redundancy and complexity of your code.

Don't forget to put your name(s) in a comment at the top of the file.

Turning the assignment in

The turn-in procedure for this:

  • tar up the lookup folder into lookup.tar
  • drop the lookup.tar file to the course account (see below)
  • Upload your code files to Gradescope, so that I can comment on them. server.js is the most important one, but your .ejs files could be useful, too.
drop cs304node lookup.tar