Skip to content
A sequelized Burger homework application
JavaScript HTML CSS
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
config
mdimg
models
nbproject
public/assets
routes
views
.gitignore
LICENSE.md
README.md
package.json
server.js

README.md

burger - Week of 15 Homework Node, Express, Sequelize, and Handlebars

Table of Contents

Overview

A burger logger with MySQL, Node, Express, and Handlebars. Be sure to follow the MVC design pattern; use Node and MySQL to query and route data in your app, and Handlebars to generate your HTML.

It is intended to demonstrate -

Usage

This application has been deployed to Heroku as per the assignment, but it can also be ran locally.

Running from Heroku

At the time when this assignment was submitted the application has been deployed to Heroku. Its URL is -

Heroku link is provided in the homework submission

NOTE: The :3000 port selection is not necessary, there is a PORT environment variable that contains the port number to be used.

URLs

The following URLs are recognized by the server and will serve pages -

  • https://deployed-server/ - displays the index page
  • https://deployed-server/index - displays the index page
  • https://deployed-server/admin - displays an admin page where burgers can be deleted. If all burgers are deleted an initialzation page will be displayed. There is a button that can be used to initiate a seeding of the table with burger data.
  • https://deployed-server/cust - displays a page where customers can be added or deleted.

Features

The following additional features have been implemented -

  • Burger list titles with a count of burgers.
  • The "Make!" button will make a persistent change to a burger's state to not devoured and the page will be updated.
  • There is an admin page that provides a means to delete any burger.
  • If all burgers are deleted a initaiize page will be presented that allows for the recreation of burger data. After the burger data is recreated the index page will be presented.
  • There is a customer admin page where customers can be deleted or added.
  • If all customers are deleted a initaiize page will be presented that allows for the recreation of customer data. After the customer data is recreated the customer admin page will be presented.

Index Page

Burger Index Page

Customer Drop Down List

Customer Drop-Down List

Burger Admin Page

Burger Admin Page

Burger Initialization Page

Note : This page is automatically presented after deleting all burgers. It cannot be accessed via https://deployed-server/init.

Burger Initialization Page

Customer Admin Page

Customer Admin Page

Customer Initialization Page

Customer Initialize Page

Architecture

I have used an architecture that differs a little from what was specified in the homework assignment. Here are the key differences -

  • method-override - I did not use this package. The assignment instructions did not indicate any need for use.
  • views folder content - this folder contains the views burger-view.js, customer-view.js, and the following Handlebars templates -
    • views/layouts/main.handlebars
    • views/index.handlebars
    • views/admin.handlebars
    • views/init.handlebars
    • views/cust.handlebars
    • views/custinit.handlebars

MVC Architecture Overview

The following diagram illustrates the basic architecture used in this application -

Burger MVC Diagram

Application Folder Structure

The following folder structure is used -

/burgerSequelize─┐              
                 │
                 ├───config     
                 │
                 ├───models     
                 │
                 ├───public     
                 │   │
                 │   └───assets 
                 │       │
                 │       ├───css
                 │       │
                 │       └───img
                 │
                 ├───routes
                 │
                 └───views      
                     │
                     └───layouts

Miscellaneous Development Notes

Assignment Alterations

Sequelize Associations

The assignment had a requirement regarding sequelize assoiciations. I had determined that a many to many association was needed between the burgers table and the customers table. The ideal associations can be illustrated as -

Ideal Table Relationships

However the current association is -

Actual Table Relationships

I implemented the association as shown above. This was done because I ran into issues and limited time. Since each burger can have only one customer this allowed me to -

  • The customers table is read just before the burgers table and before the index page is rendered. The data is stored and is then used to populate the customer drop down list.
  • The customer name is stored in a burgers table column (eatenby) when a burger is devoured. The advantage is that a customer can be deleted without affecting the devoured burger that contains their name. That burger can then be "made" and the customer name is set to null.

Extra Features

  • Table Initialization - The burger and customer tables can be seeded with data via the application. If all burgers or customers are deleted an initialization page will be displayed automatically.
  • Burger and Customer management is also an extra feature. There are admin pages (/admin and /cust) that can be used for deleting burgers or adding/deleting customers. NOTE: If all burgers or all customers are deleted a table initialize page is displayed.

Handlebars

I found Handlebars to be a useful Node package. It has a lot of potential, but the learning curve is somewhat steep in regards to the more advanced capabilities.

One challenge in using Handlebars was the customer drop down list. This was because it is nested within a portion of Handlebars code that comprises an {{#each burgers.eat }} loop. This meant that the sibling burgers.customers of burgers.eat isn't accessible directly. The solution was to use @root. For example -

    <tbody id="burgerEatTable" data={{burgers.customers.length}}>
        {{#each burgers.eat }}
        <tr>
            <form method="post" target="_self" action="/index">
                <td>{{this.id}}</td>
                <td>{{this.burger_name}}</td>
                <td>
                    <select id="burgcust" name="burgcust" type="text" class="ui fluid dropdown" required>
                        <option value="">Name?</option>
                        {{#each @root.burgers.customers}}
                            <option value={{this.id}}>{{this.customer_name}}</option>
                        {{/each}}
                    </select>
                </td>
                <td>
                    <input id="burgerid" name="burgerid" type="hidden" value={{this.id}}>
                    <input id="burgerdev" name="burgerdev" type="hidden" value={{this.devoured}}>
                    <button type="submit" class="btn btn-danger">Devour!</button>
                </td>
            </form>
        </tr>
        {{/each}}
    </tbody>

The data used in rendering is kept in an object -

var renderdata = {
    customers: [],      // customer list
    count: 0,           // total count of burgers
    eat: [],            // burgers to be eaten(devoured)
    ate: []             // burgers that have been eaten
};

HTML Notes

There are no site-owned Javascript files used in any of the rendered HTML pages. The only static file is /public/assets/css/burger.css.

Heroku Deployment

Deployment to Heroku for the most part is straight forward and easy to accomplish. However, several key steps should be noted :

  • For this application it is necessary to set up a database on Heroku and modify the config/config.json file to use the correct credentials. JawsDB is the recommended choice for a database.

  • The listening port requires some special consideration. Although it is configured, that value will not be used when running on Heroku. The following links provided useful information -

Provided the necessary information for editing the packages.json file :

https://devcenter.heroku.com/articles/deploying-nodejs

The top answer provided the details needed for managing the port number :

http://stackoverflow.com/questions/31092538/heroku-node-js-error-r10-boot-timeout-web-process-failed-to-bind-to-port-w

  • The deployment steps I used are -
  1. heroku login
  2. heroku create
  3. git push heroku master

Heroku is now ready to serve the application. After the initial deployment and subsequent file modifications, and after committing and pushing the changes to Git then only step 3 is required.

Don't forget to heroku logout when done!

Errors on Heroku

Heroku logs the output from the server application. And it can be viewed from the Heroku dashboard. This log is useful when troubleshooting issues on Heroku.

Other Heroku Behavior

When a node server application is deployed on Heroku several things will happen -

  1. Heroku will start the application as specified in the package.json file.
  2. When server application runs Heroku will assign a port to it, so it's necessary for the server application to read the PORT environment variable.
  3. If the application is idle for a period of time Heroku will kill the process. Then upon the next connection it will start the application again. The only visible side effect is that it will take a little longer to load a page on the first time after Heroku has killed the process.

My Toolbox

For this assignment I used the following development tools running on Windows -

  • NodeJS - for running the applications.
  • Netbeans 8.1 - for debugging code running in Node and secondary editor.
  • Notepad++ - Primary editor.
  • Postman - a GUI API development tool.
  • Gitkraken - a GUI Git tool.
  • Markdown Edit - a WYSIWYG tool for editing markdown files.
  • Astrogrep - a GUI grep program.
  • Evolus Pencil - for creating the diagrams used in this document.
  • Paint-DOT-Net - used for editing screen captures used in this document.

References

The following is material that I found useful -

You can’t perform that action at this time.