Skip to content

Instantly share code, notes, and snippets.

@jennli
Last active March 16, 2016 22:12
Show Gist options
  • Save jennli/b9ec5f609b6c840a71c3 to your computer and use it in GitHub Desktop.
Save jennli/b9ec5f609b6c840a71c3 to your computer and use it in GitHub Desktop.

Node

  • installation
npm install express --save
npm install -g express-generator
  • running the above commands should enable a express function:
express AwesomeAnswers
npm install 
  • package.json is where all the modules live

  • change the port to 5000 in bin/www file

var port = normalizePort(process.env.PORT || '5000');
app.set('port', port);
  • to avoid restarting server when making code changes, install nodemon
npm install -g nodemon
  • start server
nodemon bin/www
  • notice the code generated in app.js, to tell the app that it is using the express library
var app = express();
  • unlike sinatra that looks for view files in a view folder by convention, you need to configure this in node
  • so in app.js file, the following code is generated
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
  • the following is called middleware, handling for example authentications, cookieparsers
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
  • setting up a middleware function, such as before filter for unauthenticated user to stop response
// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});
  • in routes folder, make a file called question.js. create a route:
var express = require("express"),
router = express.Router();
router.get("/new", function(request, response, next){
  response.end("Create New Question");
});
  • every time when yo want to use the code elsewhere
modue.exports = router;
  • go to app.js
var questions = require('./routes/questions');
app.use('/questions', questions);
  • notice the layout view is also used in node. can optionally add in bootstrap link
doctype html
html
  head
    title= title
    link(rel='stylesheet', href='/stylesheets/style.css')
    link(rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous")
  body
    block content

Monogdb

  • monogdb
brew install mongodb
AwesomeAnswers $ mkdir /data
AwesomeAnswers $ mkdir /data/db
AwesomeAnswers $ whoami
jenniferli
AwesomeAnswers $ sudo chown jenniferli /data/db
AwesomeAnswers $ mongod
2016-03-09T11:37:54.089-0800 I CONTROL  [initandlisten] MongoDB starting : pid=57760 port=27017 dbpath=/data/db 64-bit host=Jennifers-MacBook-Pro.local
2016-03-09T11:37:54.090-0800 I CONTROL  [initandlisten] db version v3.2.0
2016-03-09T11:37:54.090-0800 I CONTROL  [initandlisten] git version: 45d947729a0315accb6d4f15a6b06be6d9c19fe7
2016-03-09T11:37:54.090-0800 I CONTROL  [initandlisten] allocator: system
2016-03-09T11:37:54.090-0800 I CONTROL  [initandlisten] modules: none
2016-03-09T11:37:54.090-0800 I CONTROL  [initandlisten] build environment:
2016-03-09T11:37:54.090-0800 I CONTROL  [initandlisten]     distarch: x86_64
2016-03-09T11:37:54.090-0800 I CONTROL  [initandlisten]     target_arch: x86_64
2016-03-09T11:37:54.090-0800 I CONTROL  [initandlisten] options: {}
2016-03-09T11:37:54.091-0800 I STORAGE  [initandlisten] wiredtiger_open config: create,cache_size=9G,session_max=20000,eviction=(threads_max=4),config_base=false,statistics=(fast),log=(enabled=true,archive=true,path=journal,compressor=snappy),file_manager=(close_idle_time=100000),checkpoint=(wait=60,log_size=2GB),statistics_log=(wait=0),
2016-03-09T11:37:54.346-0800 I NETWORK  [HostnameCanonicalizationWorker] Starting hostname canonicalization worker
2016-03-09T11:37:54.346-0800 I FTDC     [initandlisten] Initializing full-time diagnostic data capture with directory '/data/db/diagnostic.data'
2016-03-09T11:37:54.392-0800 I NETWORK  [initandlisten] waiting for connections on port 27017
  • install the mongoose module. it will allow node app to connect to mongo db
npm install mongoose --save
  • create a model folder and inside this folder make a question.js file
var mongoose = require("mongoose"),
    Schema   = mongoose.Schema;

var QuestionSchema = new Schema({
  title: {type: String},
  body:  {type: String}
});

var Question = mongoose.model("Question", QuestionSchema);

module.exports = Question;

###CRUD

  • use method-verride to enable verbs other than post and get
npm install method-override
  • questions.js in routes act as controller
var express  = require("express"),
router   = express.Router(),
Question = require("../models/question");

router.get("/new", function(request, response, next){
  // response.end("Create New Question");
  response.render("questions/new");
});

new

  • go to view/questions create a file called new.jade
  • note jade is space/indent specific
  • create a simple question form
extends ../layout

block content
  h1 Create New Question
  form(action="/questions" method="POST")
    .form-group(class="#{errors.title ? 'has-error' : ''}")
      label(for="title") Title
      input(type="text" id="title" name="title" class="form-control")
      if errors.title
        .help-block= errors.title
    .form-group
      label(for="body") Body
      textarea(id="body" name="body" class="form-control")
    input(type="submit" value="Create Question" class="btn btn-primary")
  • if only give a class without a tag name, div will be chosen by default

  • questions.js

router.get("/new", function(request, response, next){
  // response.end("Create New Question");
  response.render("questions/new", {errors: {}});
});

post

  • questions.js
router.post("/", function(request, response, next){
  var question = new Question({title: request.body.title,
                               body:   request.body.body});
  question.save(function(err, question){
    if(err) {
        response.render("questions/new", {errors: err.errors});
      } else {
        response.redirect("/questions/" + question._id);
      }
  });
});

show

router.get("/:id", function(req, res) {
    Question.findOne({_id: req.params.id}, function(err, question){
      if(err) {
        res.render('error', {message: "Question not found",
        error: {status: 404}});
      } else {
        res.render("questions/show", {question: question});
      }
    });
  });
extends ../layout

block content
  h1= question.title
  p= question.body

  a(href="/questions/#{question._id}/edit") Edit
  form(action="/questions/#{question.id}?_method=delete" method="POST")
    input(type="submit" value="Delete")

edit

router.get("/:id/edit", function(req, res){
    Question.findOne({_id: req.params.id}, function(err, question){
      if(err) {
        res.render('error', {message: "Question not found",
        error: {status: 404}});
      } else {
        res.render("questions/edit", {question: question, errors: {}});
      }
    });
  });
extends ../layout

block content
  h1 Update Question
  form(action="/questions/#{question._id}?_method=patch" method="POST")
    .form-group(class="#{errors.title ? 'has-error' : ''}")
      label(for="title") Title
      input(type="text" id="title" name="title" class="form-control" value=question.title)
      if errors.title
        .help-block= errors.title
    .form-group
      label(for="body") Body
      textarea(id="body" name="body" class="form-control")= question.body
    input(type="submit" value="Update Question" class="btn btn-primary")

update

router.patch("/:id", function(req, res){
    Question.findOne({_id: req.params.id}, function(err, question){
      if(err) {
        res.render('error', {message: "Question not found",
        error: {status: 404}});
      } else {
        question.title = req.body.title;
        question.body  = req.body.body;
        question.save(function(err){
          if(err) {
            res.render("questions/edit", {errors: err.errors, question: question});
          } else {
            res.redirect("/questions/" + question._id);
          }
        });
      }
    });
  });

destroy

  router.delete("/:id", function(req, res){
    Question.remove({_id: req.params.id}, function(err, question){
      if(err){
        res.render('error', {message: "Question not found", error: {status: 400}});
      }
      else{
        res.redirect("/questions");
      }
    });
  });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment