Who am i?


My Office



Compound.JS

An explosive MVC Framework for NodeJS




What is compoundJS?


What?


What is NodeJS?

  • JavaScript on the server-side
  • Really fast
  • The best thing since sliced bread
  • nodejs.org


What is Express?

  • Web application framework for Node
  • Provides an interface for requests and routing
  • Non-opinionated
  • expressjs.com


var express = require('express'),
    app = express();

app.get('/hello.txt', function(req, res){
  res.send('Hello World');
});
    
app.listen(3000);

If Express is so great,
why do we need Compound?
 

MVC

 

Other Goodies

  • Scaffolding
  • JugglingDB
  • Models
  • Easy routing
  • View Helpers


Now can talk we

about CompoundJS?


Generators


Using the Compound scaffolding

Generate an application

compound init myApp && cd myApp
npm install
compound generate app myApp

Generate CRUD functionality

compound generate crud user name bio age:number createdAt:date

Running the application

Start the server

compound server 3000

Controllers


Using Compound routing

exports.routes = function (map) {

// Maps CRUD methods map.resources('users');
// Maps a custom method map.get('users/login', 'users#login');
// Maps the homepage map.root('users#dashboard'); map.all(':controller/:action'); map.all(':controller/:action/:id'); };

The anatomy of a controller

load('application');
before(function () { // ...}, { only: ['edit']});
action('login', function () { render();});
action(function edit() { //...});

send()

Status code

action('destroy', function () {
   send(403); // Forbidden
});

Json

action('find', function () {
   send({
      name: 'Darth Vader',
      age: 45
   });
});

Flash Messages

In the controller

action(function create() {
    flash('info', 'User created');
    redirect(path_to.users);
});

In the view

<% var flash = request.flash('info').pop(); if (flash) { %>
   <div class="alert alert-info">
      <a class="close" data-dismiss="alert">×</a>
      <%- flash %>
   </div>
<% } %>

Views


What view renderers are supported in Compound?

  • EJS
  • Jade
  • Anything Express Supports

How do they work?

  • When the controller calls render();
  • this in the controller gets passed in


Render a different view

render('viewName');

Pass data in directly

render(undefined, { name: 'Darth Vader' });

Partials

Easily share code snippets between views
    <%- include _form %>

    Layouts

    • Stored in views/layouts
    • Defaults to [controller]_layout.[ext]
    • Falls back on application_layout.[ext]

    <html>  <head>   <title><%= title %></title>
        <%- stylesheet_link_tag('bootstrap') %>
        <%- javascript_include_tag('application') %>  </head>  <body>    <%- body %>
    </body></html>

    Juggling DB


    What Does it do? 

    • DataBase abstraction
    • Easily switch out database types
    • Common API for database interactions
    • Has tons of database adapters
      • MySQL
      • Redis
      • MongoDB
      • CouchDB
      • SQL Lite
      • ...

    What it looks like

    Defining a database schema:

    
    User = schema.define('User', {
        name:         String,
        bio:          Text,
        approved:     Boolean,
        joinedAt:     Date,
        age:          Number
    });
    
    Post = schema.define('Post', {
        title:     { type: String, length: 255 },
        content:   { type: Text },
        date:      { type: Date,    default: Date.now },
        published: { type: Boolean, default: false }
    }); 
    

    Creating Data

    User.create({
        name: 'Anakin Skywalker',
        bio: 'Jedi and pilot',
        approved: false,
        joinedAt: new Date(),
        age: 12
    }, function (err, user) {
        console.log(user);
    });    
    

    Retrieving data

    Get everybody

    User.all(function (err, users) {
        console.log(users); // Array
    });

    Get a few certain people 

    User.all({
       where: { age: 12 }
    }, function (err, users) {
        console.log(users); // Array
    });

    Get someone special

    var id = 1;
    User.find(id, function (err, user) {
        console.log(user); // Array
    });

    Updating Data

    var id = 1;User.find(id, function (err, user) {   user.updateAttributes({      name: 'Darth Vader',      bio: 'Dark Lord of the Sith',      approved: true,      age: 45   }, function (err, user) {      console.log(user);   });});

    Deleting Data

    var id = 1;
    User.find(id, function (err, user) { user.destroy(function (err) { console.log('BOOM!'); });});

    Compound Models

    module.exports = function (compound, User) {
    User.splitName = function () { return this.name.split(' '); };
    User.hasMany(Post, { as: 'posts',  foreignKey: 'userId' });
    User.belongsTo(Affiliation, { as: 'affiliation', foreignKey: 'affiliationId' });};

    Validation

    User.validatesPresenceOf('bio', 'name');
    User.validatesLengthOf('name', { min: 3 });
    


    Built in validation

    • presence
    • length
    • format
    • numericality
    • inclusion
    • exclusion

    Custom Validation

    User.validate('validateType', function (err) {
    if (this.type === 'Droid') {  err(); }}, { message: 'We don\'t serve their kind here!'});

    Testing


    Why do tests matter?

    • They stop us from releasing bugs
    • Sanity check
    • Help us to determine when
      apps are ready to release

    How do tests work in Compound?

    • Test helper attaches models and controllers
    • Tests use Sinon.js
    • Tests can be run from the terminal
      using a library such as Mocha

    How to write Unit
    tests for Compound

    function ValidAttributes () {
        return {
            name: 'Boba Fett',
            age: 1
        };
    }
    exports['models controller'] = {
        'POST create': function (test) {
            var model = new ValidAttributes;
            var create = Model.create;
            Model.create = sinon.spy(function (data, callback) {
                test.strictEqual(data, model);
                callback(null, model);
            });
            test.post('/models', {Model: model}, function () {
                test.redirect('/models');
                test.flash('info');
                test.done();
            });
        },
        ...
    };
    

    Other cool things


    Compound on the client-side

    Asset compiler

    Included compilers:

    • CoffeeScript
    • Less
    • Stylus
    • SASS

    app.configure(function(){
      app.use(compound.assetsCompiler.init());
      app.set('cssEngine', 'sass');
    });

    Compound tools

    Run compound commands from the terminal
    compound.tools.starwars = function () {
      switch (compound.args.shift()) {
        case 'episode4':        break;
        case 'episode5':        console.log('The Empire Strikes Back');
            break;
      };
    }

    In the terminal

    compound starwars episode5

    Questions?



    compoundjs

    By tysoncadenhead