Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,4 @@ Icon
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
.apdisk
57 changes: 57 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
console.log('-- Setting up server --');

const express = require('express');
const methodOverride = require('method-override');
// const cookieParser = require('cookie-parser');

// Init express app
const app = express();

// Set up middleware
app.use(methodOverride('_method')); // for delete and put
// app.use(cookieParser());
app.use(express.static('public')); // for access public files
app.use(express.json()); // parse data as json object
app.use(express.urlencoded({
extended: true
}));

// Set react-views to be default view engine
const reactEngine = require('express-react-views').createEngine();
app.set('views', __dirname + '/views');
app.set('view engine', 'jsx');
app.engine('jsx', reactEngine);

// import db, models and controllers
const createRoutes = require('./routes/routes');

const allModels = require('./database/db');

// pass in models to controller callback
// for the controller logic to decide
// on which model and view to use

const artistControls = require('./controllers/artist')(allModels);
const songControls = require('./controllers/song')(allModels)

createRoutes(app, artistControls, songControls);



// listen on port 3000 and handle server end
const PORT = 3000;

const server = app.listen(PORT, () => console.log(`-- Server setup complete! Listening on: PORT ${PORT} --
-- type 'rs' to restart server --
-- try not to break anything now... --`));

let onClose = function(){

server.close(() => {
console.log('Process terminated')
allModels.pool.end( () => console.log('Shut down db connection pool'));
})
};

process.on('SIGTERM', onClose);
process.on('SIGINT', onClose);
127 changes: 127 additions & 0 deletions buildstep.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
This is the build step for the mvc structure.

install modules

- express
- express-react-views
- method-override
- pg
- react
- react-dom

- cookie-parser


step up directories

what is :
Model
- data from controllers and sometimes views are passed here
- data can be passed into, out or manipulated.
- model will check data against the stored data in the db then supply it accordingly
- should not have no links to http, web

View
- representation of user interface.
- view will only be called by the controller when the controller has received data from the model
- react will be used as the view in this project

Controller
- controller handles the incoming http request and updates the appropriate model and identifies which view to render

Project File Structure
project/
|_ controllers/
| |_ controller-callbacks.js
|_ database/
| |_ db.js
| |_ tables.sql
| |_ seed.sql
|_ models/
| |_ queries.js
|_ node_modules/
|_ public/
|_ routes/
| |_ routes.js
|_ views/
| |_ page.jsx
|_ package-lock.json
|_ package.json
|_ app.js

controllers
- contains all logic to invoke queries from the models by providing the callbacks required by pool.query/client.query. The callback includes the appropriate view which will be rendered when the model returns/updates the data.

database
- initialises the database
- creates pool or client
- passes a pool instance to the model to enabling query
- include sql files to create tables and seed with test data

models
- contains the sql commands to create, read, update or delete data in the database.
- responsible for checking data against the database
- responsible for manipulating data
- responsible for data retrieved from controller
- responsible for sending data back to the controller when needed

public
- static files that are required by other parts of the program is included here
- examples :
• css
• javascript
• images

routes
- define your app routes(path) with http methods

views
- contains the jsx which will rendered into our html page
- uses the data retrieved by the controller to update the browser
- responsible for user interaction thru buttons, forms and input.

package.json
- you should know this
- always check version or updates

app.js
- used to initialise, invoke and link all the files for the initial configuration
- express will then listen on the port specified
- express will only execute code pertaining to the http request
- the input flow will start from the routes specified


- app.js
[] init express app
[] set up middleware
[] set react-views to be default view engine
- linking the MVC
[] import db
[] import routes
[] import the controller
[] link all to complete app methods for routes
[] listen on port 3000
- handle server end
[] shut down db connection pool
- db
[] config pg
[] create pool
[] link pool instances to models
[] export model object
- models
[] requires pool instances as a parameter
[] create crud functions
[] separate callback used by pool.query
and make a parameter provided by the controller
[] export the crud functions
- controllers
[] create callback function for the routes
[] get data from user if needed
[] manipulate data by invoking model
[] pass a callback to the model
[] decide on the view to be rendered
[] export the functions
- views
[] use react jsx to render pages
- routes
[] set up url paths
128 changes: 128 additions & 0 deletions controllers/artist.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
// create control logic to decide on
// appropriate model and view to use
// depending on a specific crud operation

// create callback function which the route uses
module.exports = (allModels) => {
/*
createControlCallback will be used by app HTTP method
request, response will be provided by app
first step is to get the model/queries wrapped in db.js
allModels.create() equals pool.query(query, callback)

defined in model/queries the query text is provided
we might need to pass data from the user input
to the model to manipulate it
we only have to pass in a callback and to render the view
*/

// control logic for create operation
// and invoked as a callback in route
let createSingleControlCallback = (req, res) => {
let userInput = req.body;
allModels.artist.createSingle(userInput, (err, result) => {
if (err) {
console.log(err, '-- create');
res.status(500).send('Bad user');
} else {
let id = result[0].id;
res.redirect(303, `/artists/${id}`)
}
})
}

let readControlCallback = (req, res) => {
allModels.artist.read((err, result) => {
if (err) {
console.log(err, '-- read');
res.status(500).send('Bad user');
} else {
res.render('artist/index', { result })
}
})
}

let readSingleControlCallback = (req, res) => {
let id = req.params.id;
allModels.artist.readSingle(id, (err, result) => {
if (err) {
console.log(err, '-- readSingle');
res.status(500).send('Bad user');
} else {
res.render('artist/show', { ...result[0] })
}
})
}

let editSingleControlCallback = (req, res) => {
let id = req.params.id;
allModels.artist.readSingle(id, (err, result) => {
if (err) {
console.log(err, '-- editSingle');
res.status(500).send('Bad user');
} else {
res.render('artist/edit', { ...result[0] })
}
})
}

let updateSingleControlCallback = (req, res) => {
let values = [req.body.name,
req.body.photo_url,
req.body.nationality,
req.params.id,
]
allModels.artist.updateSingle(values, (err, result) => {
if (err) {
console.log(err, '-- updateSingle');
res.status(500).send('Server error...')
} else {
res.redirect(303, `/artists/${req.params.id}`)
}
})
}

let destroySingleControlCallback = (req, res) => {
let id = req.params.id;
allModels.artist.destroySingle(id, (err, result) => {
if (err) {
console.log(err, '-- destroySingle');
res.status(500).send('Server error')
} else {
res.redirect(301, '/artists/');
}
})
}

let newFormControlCallback = (req, res) => {
res.render('artist/new');
}

let redirectHomeControlCallback = (req, res) => {
res.redirect(301, '/artists/');
}

let readSongsControlCallback = (req, res) => {
let id = req.params.id;
allModels.artist.readSongs(id, (err, result) => {
if (err) {
console.log(err, '-- readSongs');
res.status(500).send('Server error');
} else {
res.render('artist/artistSongs', {result})
}
})
}

return {
createSingle: createSingleControlCallback,
read: readControlCallback,
readSongs: readSongsControlCallback,
readSingle: readSingleControlCallback,
editSingle: editSingleControlCallback,
updateSingle: updateSingleControlCallback,
destroySingle: destroySingleControlCallback,
newForm: newFormControlCallback,
redirectHome: redirectHomeControlCallback,
}
}
Loading