MVC

MVC stands for Model View Controller

Each of these conceptual parts of the app will be broken up into different files.

This will give structure to our app and allow some code reuse.

We will be using this app as a reference: https://github.com/wdi-sg/mvc-template

Pairing Exercise

Clone the MVC template repo.

db setup

Make sure db.js has the correct configuration for your DB (db name, user name).

Make sure you have a table called students:

CREATE TABLE IF NOT EXISTS students (
    id SERIAL PRIMARY KEY,
    name TEXT,
    phone TEXT,
    email TEXT
);
db seed

Add some students into your DB, if you don't have any:

INSERT INTO students
(name, phone, email)
VALUES
('William Smith', '(415)555-5555', 'bill@example.com');

INSERT INTO students
(name, phone, email)
VALUES
('Bob Jones', '(415)555-5555', 'bob@example.com');
routes

Add one route to the routes file. /students

Assume you will have a new method in pokemon: pokemons.students

routes.js

app.get('/students', pokemons.students);
controllers

Inside of controllers/pokemon.js add one method to the pokemon controller file for this route.

Don't forget to make a key for the method at the bottom of the file.

Use response.send('banana') to test it.

models

Inside of models/pokemon.js create a new method getStudent in the pokemon model file that queries for a single student by name.

const getStudent = (name) => {

It runs this query (change the below to be dynamic)

SELECT * FROM students WHERE name='kevin';
  • the method has to take the student name as a parameter to put in the WHERE clause
  • console.log the result in the model

Note: don't forget to make a key for the method at the bottom of the file.

call model from controller

Call your model method from your controller

db.pokemon.getStudent(name)

Watch for the console.log

pass callback to model

Inside of conroller/pokemon.js change your controller method to define and pass a callback to the model.

const whenDoneInModel = (err, result)=>{
  console.log("wow, done");
};

db.pokemon.getStudent(name, whenDoneInModel);
Run the callback

In models/pokemon.js change the function signature in the model to use this new parameter. (i.e., the thing you pass in in the controller must match what you have in the model)

const getStudent = (name, callback) => {
  // run the query
  ...
    // when the query is done, call the callback

    // pass the result of the query
    callback(err, results.rows)
respond with the model result

Inside of conroller/pokemon.js move the response.send into the callback.

const whenDoneInModel = (err, result)=>{
  console.log("wow, done");
  response.send( result )
};

db.pokemon.getStudent(name, whenDoneInModel);

Further

In the above exercise, you added methods to the files that already exist.

This is not how you would normally do it, because you will have one controller and model for each type of data. (most likely one for each table, excluding some join tables)

Now add a new model, dogs.

You must add the require of this model file in db.js

You must require the file and call it, passing in the variable pool.

You must export it at the bottom of db.js

const dogsModelFunc = require('./models/dogs.js');
const dogsModel = dogsModelFunc( pool );

...
module.exports = {

  ...
  dogsModel: dogsModel
};

An empty model looks like this:

module.exports = (dbPoolInstance) => {

  let something = (callback)=>{
    //query
  };

  return {
    something:something,
  };
}

Add a controller file. It must be required in the routes.js file.

You must pass the variable called allModels to the require.

const dogs = require('./controllers/dogs')(allModels);
app.get('/dogs', something.getAllDogs);

An empty controller looks like this:

module.exports = (db) => {

  const index = (request, response) => {
  };

  return {
    index: index,
  };
}

Add a get route to render a form to create a single class (GET /dogs/new)

Add a model method to take in the POST request this form creates. This is a new controller file.

Further

Add owners model and controller to this app. Don't create any view (jsx) files yet.

Create:

GET /owners/new POST /owners GET /owners/:id

Further

Add the /dogs/:id route.

Show the dog's owner by making a nested query in the model using this syntax:

db.dogs.getDog(request.params.id, (dogError, dog)=>{

  let ownerId = dog.owner_id;

  db.owners.getOwner(ownerId, (ownerError, owner)=>{
    // response send goes here
  })
});

Further

In the model, check result.rows. If it's empty, don't give back result.rows, instead give back an error and check for it in the controller.

Further

Fill in the rest of the restful routes for dogs and owners.

results matching ""

    No results matching ""