<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Thieves Like Us]]></title><description><![CDATA[Opinions and code. But mostly opinions.]]></description><link>http://brianmajewski.com/</link><generator>Ghost 0.6</generator><lastBuildDate>Sat, 14 Mar 2026 14:28:20 GMT</lastBuildDate><atom:link href="http://brianmajewski.com/tag/node/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[(Re)Learning Backbone Part 12]]></title><description><![CDATA[<p><strong>Permissions</strong> <br>
For the last piece of our application, we are going to require that a user have "admin" permissions to delete another user. We created a cheat way to add permissions to our users earlier in the series. Using that, or Mongohub, ensure we have one user with "admin" as</p>]]></description><link>http://brianmajewski.com/2015/03/06/relearning-backbone-part-12/</link><guid isPermaLink="false">aca10dc4-ffec-4b56-8a3f-73503c232f98</guid><category><![CDATA[backbone]]></category><category><![CDATA[javascript]]></category><category><![CDATA[node]]></category><dc:creator><![CDATA[Brian Majewski]]></dc:creator><pubDate>Fri, 06 Mar 2015 05:14:49 GMT</pubDate><media:content url="http://brianmajewski.com/content/images/2015/03/Fuyu_Persimmon_-Diospyros_Kaki-.jpg" medium="image"/><content:encoded><![CDATA[<img src="http://brianmajewski.com/content/images/2015/03/Fuyu_Persimmon_-Diospyros_Kaki-.jpg" alt="(Re)Learning Backbone Part 12"><p><strong>Permissions</strong> <br>
For the last piece of our application, we are going to require that a user have "admin" permissions to delete another user. We created a cheat way to add permissions to our users earlier in the series. Using that, or Mongohub, ensure we have one user with "admin" as a permission, and one user without. Let's start logged in as the user <em>without</em> permissions.</p>

<p><strong>Update The Server</strong></p>

<p>On the server, we know who the user making a request is due to the token they present on every call, but we don't have the User object. We could make a DB call to see if they have the right permissions. This could become a burden on our server. We could use a server side session to store the User, but again, this may not scale well. The easiest way to determine the permissions is to have the user tell us. We can add the permissions to the token before we encrypt it. Then when we decrypt it, which we do on every authenticated call, we can access the permissions it contains.  Let's update our <code>authenticate</code> endpoint</p>

<p><em>/app/routes/user.js</em>  </p>

<pre><code class="language-javascript">userRouter.post('/authenticate', function (req, res) {  
    User.findOne({
        email: req.body.email
    }).select('name email password').exec(function (err, user) {
        if (err) throw err;

        if (!user) {
            res.json({success: false, message: 'User not found'});
        } else {
            var validPassword = user.comparePassword(req.body.password);
            if (!validPassword) {
                res.json({success: false, message: 'Wrong password'});
            } else {
                var token = jwt.sign({
                    name: user.name,
                    email: user.email,
                    _id: user._id,
                    permissions: user.permissions
                }, superSecret, {
                    expiresInMinutes: 1440
                });

                res.json({
                    success: true,
                    message: 'login ok',
                    token: token,
                    _id: user._id
                });
            }
        }
    });
});
</code></pre>

<p>We simply added the one line</p>

<pre><code>permissions: user.permissions  
</code></pre>

<p>in our signing method.</p>

<p>Now, let's update our DELETE route to check for admin. For convenience, and consistency with our client, let's throw <a href="http://underscorejs.org/">underscore.js</a> into the server.</p>

<pre><code>npm install underscore --save  
</code></pre>

<p>and add it to the top of our user routes</p>

<pre><code>var _ = require('underscore');  
</code></pre>

<p>and finally update the DELETE route</p>

<pre><code class="language-javascript">.delete(function (req, res) {
    if (_.contains(req.decoded.permissions, 'admin')){
        User.remove({_id: req.params.user_id}, function (err, user) {
            if (err) res.send(err);
                res.json({});
            })
        } else {
            return res.status(403).send({success: false, message: 'User is not authorized to delete users'});
        }
    });
</code></pre>

<p>We check if the permissions property of our decoded token contains "admin", and if not, throw a 403 error. Refresh the server and try to delete a user. You should see the error in the console window and the list of users remaining the same.</p>

<p>For this error, we don't want to redirect the user anywhere but it would be nice to let them know that the error occured.  Let's trap for the 403, like we did the 401, and popup an alert. For our popups, we'll be using <a href="https://github.com/CodeSeven/toastr">Toastr</a>, so let's add it with bower, update <code>require-main.js</code>, and include its CSS on our index page.</p>

<pre><code>bower install toastr --save  
</code></pre>

<p><em>require-main.js</em>  </p>

<pre><code class="language-javascript">requirejs.config({  
    baseUrl: "app",

    paths: {
        "jquery": "../components/jquery/dist/jquery",
        "underscore": "../components/underscore/underscore",
        "backbone": "../components/backbone/backbone",
        "handlebars": "../components/handlebars/handlebars.amd",
        "text": "../components/requirejs-text/text",
        "hbs": "../components/require-handlebars-plugin/hbs",
        "datatables": "../components/datatables/media/js/jquery.dataTables",
        "datatables-bootstrap3": "../components/datatables-bootstrap3-plugin/media/js/datatables-bootstrap3",
        "bootstrap-modal": "../components/bootstrap/js/modal",
        "backbone.bootstrap-modal": "../components/backbone.bootstrap-modal/src/backbone.bootstrap-modal",
        "stickit" : "../components/backbone.stickit/backbone.stickit",
        "toastr" : "../components/toastr/toastr"
    }
});

require(['main', 'app']);  
</code></pre>

<p><em>index.html</em>  </p>

<pre><code>&lt;link rel="stylesheet" href="components/toastr/toastr.css"&gt;  
</code></pre>

<p>With the library in place, let's update our error handler. Remember to require toastr at the top of the file.</p>

<p><em>app/main.js</em>  </p>

<pre><code class="language-javascript">$.ajaxSetup({
    statusCode: {
        401: function (context) {
            mediator.trigger('router:navigate', {route: 'login', options: {trigger: true}});
        },

        403: function(context){
            toastr.options = {
                "closeButton": false,
                "debug": false,
                "newestOnTop": false,
                "progressBar": false,
                "positionClass": "toast-top-center",
                "preventDuplicates": false,
                "onclick": null,
                "showDuration": "300",
                "hideDuration": "1000",
                "timeOut": "5000",
                "extendedTimeOut": "1000",
                "showEasing": "swing",
                "hideEasing": "linear",
                "showMethod": "fadeIn",
                "hideMethod": "fadeOut"
            };

            toastr["error"](context.responseJSON.message);
        }
    },
    beforeSend: function (xhr) {
        var token = window.localStorage.getItem(globals.auth.TOKEN_KEY);
        xhr.setRequestHeader('x-access-token', token);
    }
});
</code></pre>

<p>You can configure your popup however you like. These options are the ones generated from the library's demo site. We configure the popup, then display the error message our backend returned to us.</p>

<p>One last tweak is needed. Backbone is optimistic when you ask to destroy a model, and will remove it from any collections it is in. Since we may not want that to happen, we pass in a <em>wait</em> property to our <em>destroy</em> method. Let's update that</p>

<p><em>app/users/listView.js</em>  </p>

<pre><code class="language-javascript">deleteUser: function(e){  
    var self = this;
    var id = $(e.currentTarget).attr('data-id');
    var user = this.collection.get(id);
    user.destroy({wait: true}).done(function(){
        self.collection.remove(user);
        self.render();
    });
}
</code></pre>

<p>Now, ideally, we don't want the user to even be given the option to press the delete button. All of this error handling is neccesary to protect our data but we shouldn't be giving users options they don't have. Much like checking for authentication, we are going to create a way for our views to check for authorizations.</p>

<p>Let's create a simple Permissions object that we can create when the user logs in.</p>

<p><em>app/permissions.js</em>  </p>

<pre><code class="language-javascript">define(function (require) {

    'use strict';

    var _ = require('underscore');

    return function(permissions){
        this.isAdmin = function(){
            return _.contains(permissions, 'admin');
        };
    }
});
</code></pre>

<p>We'll pass in the permissions array from the user when we create this, then for convenience we expose an <em>isAdmin</em> function. This can be expanded as needed. Common patterns include 'has one of these permissions' and 'has all of these permissions'. Let's update our <code>app</code> object</p>

<p><em>app/app.js</em>  </p>

<pre><code class="language-javascript">var Permissions = require('permissions');  
var _permissions;

function _initializeUser() {  
    var d = $.Deferred();
    if (_isAuthenticated() &amp;&amp; !_user) {
        _user = new User({_id: window.localStorage.getItem(globals.auth.USER_KEY)});
        _user.fetch().success(function () {
            mediator.trigger('page:updateUserInfo');
            _permissions = new Permissions(_user.get('permissions'));
            d.resolve();
        });
    } else {
        d.resolve();
    }
    return d.promise();
}

function _getPermissions() {  
    return _permissions;
}

return {  
    isAuthenticated: _isAuthenticated,
    initialize: _initialize,
    initializeUser: _initializeUser,
    getApplicationInfo: _getApplicationInfo,
    getUser: _getUser,
    getPermissions: _getPermissions
}
</code></pre>

<p>Now, let's update our user list template and view to not show the delete button unless the user is an admin.</p>

<p><em>app/users/list.hbs</em>  </p>

<pre><code class="language-markup">&lt;div class="pull-right"&gt;  
    &lt;button data-id="{{_id}}" class="btn btn-danger btn-sm js-deleteUser"&gt;Delete&lt;/button&gt;
    {{#if ../admin}}&lt;button data-id="{{_id}}" class="btn btn-success btn-sm js-editUser"&gt;Edit&lt;/button&gt;{{/if}}
&lt;/div&gt;  
</code></pre>

<p>Here we check the value of <em>../admin</em> to conditionally show the button. We are using the <code>../</code> notation because we are inside of the <code>users</code> loop and we will be storing our admin value one level up.</p>

<p><em>_app/users/listView.js (render)</em>  </p>

<pre><code class="language-javascript">render: function () {  
    this.$el.html(template({
        users: this.collection.toJSON(), 
        admin: app.getPermissions().isAdmin() 
    }));
    this.$('table').DataTable({
        "aoColumns": [
            null,
            null,
            null,
            { "bSortable": false }
        ]
    });
return this;  
}
</code></pre>

<p>After adding an app dependency to our object, we add an <em>admin</em> value to the context object we pass our template for rendering. Refresh the page, and the button is gone. Log in now as a user with admin permissions and verify that the button is still visible and in fact deletes the user.</p>

<p><strong>Next Steps</strong></p>

<p>In our final installment, we will make a few tweaks to the code and talk about what could be some next steps.</p>

<p>(The code at this state in the project can be checked out at commit: <a href="https://github.com/bmajewski/relearning-backbone/commit/7d3bc57ffc8ec09c4e28b739da9ba3d20da37a2c">7d3bc57ffc8ec09c4e28b739da9ba3d20da37a2c</a>)</p>]]></content:encoded></item><item><title><![CDATA[(Re)Learning Backbone Part 10]]></title><description><![CDATA[<p><strong>Logging In</strong></p>

<p>When we last left off, we had enforced authentication on our <code>users</code> endpoints and provided an endpoint to authenticate against. Today, we are going to add a Login screen and route to present our credentials to the backend. Upon success, we'll store the returned token and present it</p>]]></description><link>http://brianmajewski.com/2015/03/03/relearning-backbone-part-10/</link><guid isPermaLink="false">fba991ee-c41d-4fa5-8755-101d041ff747</guid><category><![CDATA[backbone]]></category><category><![CDATA[javascript]]></category><category><![CDATA[node]]></category><category><![CDATA[authentication]]></category><dc:creator><![CDATA[Brian Majewski]]></dc:creator><pubDate>Wed, 04 Mar 2015 01:47:29 GMT</pubDate><media:content url="http://brianmajewski.com/content/images/2015/02/free_login_sign_up_buttons_by_button_finder-d4pyzqo.jpg" medium="image"/><content:encoded><![CDATA[<img src="http://brianmajewski.com/content/images/2015/02/free_login_sign_up_buttons_by_button_finder-d4pyzqo.jpg" alt="(Re)Learning Backbone Part 10"><p><strong>Logging In</strong></p>

<p>When we last left off, we had enforced authentication on our <code>users</code> endpoints and provided an endpoint to authenticate against. Today, we are going to add a Login screen and route to present our credentials to the backend. Upon success, we'll store the returned token and present it on all subsequent requests.</p>

<p>Let's start by introducing a <code>globals</code> object. I like to create an object to hang constant values off of that are needed throughout the app.</p>

<p><em>/app/globals.js</em>  </p>

<pre><code class="language-javascript">define(function (require) {

    'use strict';

    return {
        auth: {
            TOKEN_KEY: 'authToken',
            USER_KEY: 'userId'
        },
        urls: {
            AUTHENTICATE: '/api/authenticate'
        }
    }
});
</code></pre>

<p>Here we've defined two keys we are going to use to store and retrieve authentication data and the URL we need to hit to authenticate. For entities, like <em>User</em>, we store the URL with the model, but for URLs that don't neatly map to a model, I like to keep them here in globals.</p>

<p>So, with our authentication in place, if we try to hit <code>/#users</code>, we'll get a 401 error when we call the <code>/api/users</code> endpoint, and our screen will only show our header and our footer. Let's have our app respond to 401 errors by redirecting the user to a login screen.</p>

<p>In <code>/app/main.js</code>, before we create our Router, add the following code:</p>

<pre><code class="language-javascript">$.ajaxSetup({
    statusCode: {
        401: function () {
            console.log('AJAX Handler - 401 Error Received');
            mediator.trigger('router:navigate', {route: 'login', options: {trigger: true}});
        }
    }
});
</code></pre>

<p>We are using jQuery to make a global change to our AJAX handling. Now, any AJAX call that gets a 401 error will get trapped and we'll trigger the router to take us to our login page. Let's update our router to handle this.</p>

<pre><code class="language-javascript">routes: {  
        '': 'home',
        'home': 'home',
        'users': 'users',
        'login': 'login'
    },

login: function() {  
    console.log('routing - login');
    require(['login/view'], function(View){
        mediator.trigger('page:displayView', new View());
    });
}
</code></pre>

<p>We've updated our route table to include a login path, and created a handler for it. This should seem familiar by now. We'll need a template and a view.</p>

<p><em>/app/login/template.hbs</em>  </p>

<pre><code class="language-markup">&lt;div class="well"&gt;  
    &lt;h4&gt;&lt;b&gt;Login&lt;/b&gt;&lt;/h4&gt;
&lt;/div&gt;  
&lt;div class="alert alert-warning" style="display: none;"&gt;&lt;/div&gt;  
&lt;form class="form-horizontal login-form"&gt;  
    &lt;div class="form-group"&gt;
        &lt;label for="email" class="col-lg-2 control-label"&gt;Email&lt;/label&gt;

        &lt;div class="col-lg-10"&gt;
            &lt;input type="text" class="form-control" id="email" placeholder="Email"&gt;
        &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="form-group"&gt;
        &lt;label for="password" class="col-lg-2 control-label"&gt;Password&lt;/label&gt;

        &lt;div class="col-lg-10"&gt;
            &lt;input type="password" class="form-control" id="password" placeholder="Password"&gt;
        &lt;/div&gt;
    &lt;/div&gt;
    &lt;button type="button" class="btn btn-primary js-login pull-right"&gt;Login&lt;/button&gt;
&lt;/form&gt;  
</code></pre>

<p>This is a simple form that will allow us to collect an email address and a password. It also has an <em>alert</em> div we will use to display error messages and a submit button with the class <code>js-login</code> which will trigger the submission action.</p>

<p><em>/app/login/view.js</em>  </p>

<pre><code class="language-javascript">define(function (require) {

    'use strict';

    var Backbone = require('backbone');
    var globals = require('globals');
    var mediator = require('mediator');
    var template = require('hbs!login/template');

    return Backbone.View.extend({
        el: '#content',

        events: {
            'click .js-login': 'login'
        },

        render: function () {
            this.$el.html(template());
            return this;
        },

        login: function (e) {
            e.preventDefault();
            var formValues = {
                email: this.$('#email').val(),
                password: this.$('#password').val()
            };
            this.$('.alert').hide();
            console.log('login with ', formValues);
            $.ajax({
                url: globals.urls.AUTHENTICATE,
                type: 'POST',
                dataType: 'json',
                data: formValues,
                success: function(response){
                    if (response.success){
                        window.localStorage.setItem(globals.auth.TOKEN_KEY, response.token);
                        window.localStorage.setItem(globals.auth.USER_KEY, response._id);
                        mediator.trigger('router:navigate', {route:'home', options: {trigger: true}});
                    } else {
                        self.$('.alert-warning').text(response.message).show();
                    }
                }
            });
        }
    });
});
</code></pre>

<p>This is a standard view that listens for a click event on our submit button. When it receives one, we go to the <em>login</em> method.</p>

<p>Here, we get the values from the form fields. If the alert box is visible, we hide it. Finally, we make an AJAX call to our authentication endpoint, using the URL we defined in our globals. </p>

<p>If you remember, our authentication routine does not send back an HTTP error code. This allows us to handle any errors here. In our case, the <em>else</em> block, when the response message <em>success</em> property is false, takes the message returned from the server, adds it to the alert box and makes it visible.</p>

<p>When we successfully enter our credentials, we use local storage to store the auth token and the user id that was returned to us. Finally, we navigate to the home screen. Later, we can add code to redirect the user to their original destination but for now, we'll go home.</p>

<p>So what happens if we try to go to <code>/#users</code> again. Another 401 error! Just because we logged in once, the server has no idea that it is still us unless we tell it. To do this, we will include that token we just received in the header of all our AJAX calls. Go back to where we trapped for the 401 error and update the handler</p>

<pre><code class="language-javascript">$.ajaxSetup({
    statusCode: {
        401: function (context) {
            mediator.trigger('router:navigate', {route: 'login', options: {trigger: true}});
        }
    },
       beforeSend: function (xhr) {
        var token = window.localStorage.getItem(globals.auth.TOKEN_KEY);
        xhr.setRequestHeader('x-access-token', token);
    }
});
</code></pre>

<p>We've added the <em>beforeSend</em> method. This will retrieve the token from local storage, and set the <em>x-access-token</em> header to that value. If you recall, that is where our authenticated routes look for the token when determining if the caller is authenticated. Now if we hit our users page, the token we previously stored will be sent with our call, we'll be authenticated, and the page will display properly.</p>

<p>If you need to try again, you can use your browser's dev tools to remove the token from local storage, effectively logging you out. Let's make this a little easier on ourselves. Later, we'll be customizing our header view with information specific to the current user. For now, let's add a <em>logout</em> link.</p>

<p>In <code>/page/headerTemplate.hbs</code> replace the <code>[Navigation Elements]</code> place holder with</p>

<pre><code class="language-markup">&lt;li&gt;&lt;a href="#logout"&gt;&lt;span class="fa fa-lg fa-times-circle-o"&gt;&lt;/span&gt; Logout&lt;/a&gt;&lt;/li&gt;  
</code></pre>

<p>and update your router</p>

<p><em>/app/router.js</em>  </p>

<pre><code class="language-javascript">routes: {  
    '': 'home',
    'home': 'home',
    'users': 'users',
    'login': 'login',
    'logout': 'logout'
},

logout: function() {  
    window.localStorage.removeItem(globals.auth.TOKEN_KEY);
    window.localStorage.removeItem(globals.auth.USER_KEY);    
    this.home();
 }
</code></pre>

<p>This simply deletes our authentication info and sends the user to the home page. If it seems a little messy that we are messing with local storage in different parts of our app, you're right. Later when we coordinate loading the currently authenticated user, we'll create some convenience methods that we can trigger with messages through the mediator.</p>

<p><strong>Next Steps</strong></p>

<p>When we load our app, we will want to make sure we have the user object associated with the currently logged in user. We've already stored the id, so it is just a matter of loading the user. With that User, we'll customize the header. Additionally, we relied on the 401 error to redirect us to the login page. We'll be adding an <em>isAuthenticated</em> check to the router itself so that we can redirect to the login screen without needing to make a server call round trip.</p>

<p><em>(You can check out the project at it's current state at commit: <a href="https://github.com/bmajewski/relearning-backbone/commit/8a0a2b3c06575454a7ffae2b03b579d3bc47acba">8a0a2b3c06575454a7ffae2b03b579d3bc47acba</a>)</em></p>]]></content:encoded></item><item><title><![CDATA[(Re)Learning Backbone Part 8]]></title><description><![CDATA[<p>(Note: The code for this project at this point in our progress can be downloaded from <a href="https://github.com/bmajewski/relearning-backbone">Github</a> at commit: <a href="https://github.com/bmajewski/relearning-backbone/commit/c29507a245dce5f7cd3b900a72e8dbeac0fc3238">c29507a245dce5f7cd3b900a72e8dbeac0fc3238</a>)</p>

<p><strong>A Little Cleanup</strong></p>

<p>Back when we created the REST endpoints, we returned some "friendly" success messages. Without a UI, these made it easy to see when the requests went through.</p>]]></description><link>http://brianmajewski.com/2015/02/24/relearning-backbone-part-8/</link><guid isPermaLink="false">8a30c2da-9991-471c-a2e3-d2282ebf2ff3</guid><category><![CDATA[backbone]]></category><category><![CDATA[javascript]]></category><category><![CDATA[node]]></category><category><![CDATA[bower]]></category><category><![CDATA[bootstrap]]></category><category><![CDATA[modal]]></category><category><![CDATA[data-binding]]></category><category><![CDATA[stickit]]></category><dc:creator><![CDATA[Brian Majewski]]></dc:creator><pubDate>Tue, 24 Feb 2015 05:02:02 GMT</pubDate><media:content url="http://brianmajewski.com/content/images/2015/02/oIpwxeeSPy1cnwYpqJ1w_Dufer-Collateral-test.jpg" medium="image"/><content:encoded><![CDATA[<img src="http://brianmajewski.com/content/images/2015/02/oIpwxeeSPy1cnwYpqJ1w_Dufer-Collateral-test.jpg" alt="(Re)Learning Backbone Part 8"><p>(Note: The code for this project at this point in our progress can be downloaded from <a href="https://github.com/bmajewski/relearning-backbone">Github</a> at commit: <a href="https://github.com/bmajewski/relearning-backbone/commit/c29507a245dce5f7cd3b900a72e8dbeac0fc3238">c29507a245dce5f7cd3b900a72e8dbeac0fc3238</a>)</p>

<p><strong>A Little Cleanup</strong></p>

<p>Back when we created the REST endpoints, we returned some "friendly" success messages. Without a UI, these made it easy to see when the requests went through. Now that we are going to be using them, let's have them return something more useful.</p>

<p>For GET <code>/api/users</code> and GET <code>/api/users/:user_id</code>, we already return an array or a single user, as appropriate. Let's do the same for POST <code>/api/users</code> and PUT <code>/api/users/:user_id</code>. For these, we will return the User that was either just created or was updated. There is no user we can return after a DELETE, so we can return an empty object.  Our updated <code>/app/routes/user.js</code> code now looks like this:</p>

<pre><code class="language-javascript">var bodyParser = require('body-parser');  
var User = require('../models/user');

module.exports = function (app, express) {  
    var userRouter = express.Router();

    userRouter.get('/', function (req, res) {
        res.json({message: 'api is loaded'});
    });

    userRouter.route('/users')
        .post(function (req, res) {
            var user = new User();
            user.name = req.body.name;
            user.email = req.body.email;
            user.password = req.body.password;

            user.save(function (err) {
                if (err) {
                    if (err.code === 11000) {
                        return res.json({success: false, message: 'Duplicate username.'});
                    } else {
                        return res.send(err);
                    }
                } else {
                    res.json(user);
                }

            });
        })
        .get(function (req, res) {
            User.find(function (err, users) {
                if (err) {
                    res.send(err);
                }
                res.json(users);
            })
        });

    userRouter.route('/users/:user_id')
        .get(function (req, res) {
            User.findById(req.params.user_id, function (err, user) {
                if (err) res.send(err);
                res.json(user);
            })
        })
        .put(function (req, res) {
            User.findById(req.params.user_id, function (err, user) {
                if (err) res.send(err);

                if (req.body.name) user.name = req.body.name;
                if (req.body.email) user.email = req.body.email;
                if (req.body.password) user.password = req.body.password;

                user.save(function (err) {
                    if (err)res.send(err);
                    res.json(user);
                });
            });
        })
        .delete(function (req, res) {
            User.remove({_id: req.params.user_id}, function (err, user) {
                if (err) res.send(err);
                res.json({});
            })
        });

    return userRouter;
};
</code></pre>

<p><strong>Adding Actions To Our User List</strong></p>

<p>We're going to want to be able to Add a User, and Delete or Edit a specific user. Let's start with Delete.</p>

<p>Let's add a column to our table on the right side to hold user specific actions. Add a blank <code>&lt;th&gt;&lt;/th&gt;</code> to our <code>&lt;thead&gt;</code> and a <code>&lt;td&gt;&lt;/td&gt;</code> in our <em>#each</em> loop. In the <code>&lt;td&gt;</code> add the following:</p>

<pre><code>&lt;button data-id="{{_id}}" class="btn btn-danger btn-sm js-deleteUser"&gt;Delete&lt;/button&gt;  
</code></pre>

<p>This will display a Delete button. We've added a <code>data=id</code> attribute to hold the User id. This will allow us to specify which User to delete. We've also added a <code>js-deleteUser</code> class to the button. We are using the <code>js-*</code> pattern for class names that indicate functionality as opposed to design.</p>

<p>Now, let's add the functionality to perform the delete in <code>/app/users/listView.js</code>. Under the <em>el</em> declaration, add an <em>events</em> block</p>

<pre><code class="language-javascript">events: {  
    'click .js-deleteUser': 'deleteUser'
},
</code></pre>

<p>On the left, we define an event and a CSS selector for the event, and on the right, a method to handle the event. In this case, we are trapping for a <em>click</em> event on any item with a class of <em>js-deleteUser</em>, and delegating to the <em>deleteUser</em> method to handle it. Let's create that method now.</p>

<pre><code class="language-javascript">deleteUser: function(e){  
    var self = this;
    var id = $(e.currentTarget).attr('data-id');
    var user = this.collection.get(id)
    user.destroy().done(function(){
        self.collection.remove(user);
        self.render();
    });
}
</code></pre>

<p>Here we ask the object that triggered the event for the value of its <em>data-id</em> attribute, and retrieve that user from our collection. We trigger the <em>destroy</em> method provided by Backbone, we will call our REST backend. When it is complete, we remove the user from the collection, and redraw the table.</p>

<p>Reload the app, and delete a user. If you don't have any to delete, you can either use the Postman extension to add some more, or, we can forge ahead and wire in an Add button.</p>

<p>We want to have a modal dialog popup with a form that will allow us to enter in a name, an email, and a password, along with a button to save it. With a little bit of configuration, we can use this same dialog to edit an existing user. To do the heavy lifting, we're going to add in a few libraries. Since we are using Bootstrap for our CSS, let's just dive in and grab the whole framework. We'll still only pull in what we need as we need it. We're also going to use a Backbone plugin to wrap the Bootstrap modal functionality so that we can easily interact with it from our views. Adding <a href="https://github.com/powmedia/backbone.bootstrap-modal">backbone.bootstrap-modal</a> with bower will pull both libraries in. </p>

<p>We also want to incorporate data-binding. Data-binding is one of the <strong>big</strong> features that frameworks like Angular and Ember pitch as a benefit. We're going to get all the functionality they provide with much greater and explicit control of when we use binding and how for a lighter footprint on our page. For this, we will use <a href="http://nytimes.github.io/backbone.stickit/">stickit</a> from the NYTimes. Install both these libraries with</p>

<pre><code>bower install backbone.bootstrap-modal backbone.stickit --save  
</code></pre>

<p>and update the <code>require-main.js</code> file</p>

<pre><code class="language-javascript">"bootstrap-modal": "../components/bootstrap/js/modal",
"backbone.bootstrap-modal": "../components/backbone.bootstrap-modal/src/backbone.bootstrap-modal",
"stickit" : "../components/backbone.stickit/backbone.stickit"
</code></pre>

<p>Let's once again update our list view, with an Add button at the top of the page and an Edit button next to the Delete.</p>

<p><em>/app/users/list.hbs</em></p>

<pre><code class="language-markup">&lt;div class="well"&gt;  
    &lt;h4&gt;&lt;b&gt;Users&lt;/b&gt;&lt;span class="pull-right"&gt;&lt;button class="btn btn-primary js-editUser"&gt;Add User&lt;/button&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;/div&gt;  
&lt;table class="table table-bordered table-striped"&gt;  
    &lt;thead&gt;
    &lt;th&gt;ID&lt;/th&gt;
    &lt;th&gt;Email&lt;/th&gt;
    &lt;th&gt;Name&lt;/th&gt;
    &lt;th&gt;&lt;/th&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
    {{#each users}}
        &lt;tr&gt;
            &lt;td&gt;{{_id}}&lt;/td&gt;
            &lt;td&gt;{{email}}&lt;/td&gt;
            &lt;td&gt;{{name}}&lt;/td&gt;
            &lt;td&gt;
                &lt;div class="pull-right"&gt;
                    &lt;button data-id="{{_id}}" class="btn btn-danger btn-sm js-deleteUser"&gt;Delete&lt;/button&gt;
                    &lt;button data-id="{{_id}}" class="btn btn-success btn-sm js-editUser"&gt;Edit&lt;/button&gt;
                &lt;/div&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    {{/each}}
    &lt;/tbody&gt;
&lt;/table&gt;  
</code></pre>

<p>Since we are using the same code for both editing and adding, we've added the same class, <em>js-editUser</em> to both. To the Edit button, we add a <em>data-id</em> attribute. If we were going to add any more actions, we might consider putting the ID on the row once for all the fields. For now, we'll stick with this.</p>

<p>Let's update our List view to trap for the new event.</p>

<pre><code class="language-javascript">events: {  
    'click .js-deleteUser': 'deleteUser',
    'click .js-editUser': 'editUser'
},
</code></pre>

<p>and</p>

<pre><code class="language-javascript">editUser: function(e) {  
    var id = $(e.currentTarget).attr('data-id');
    var options = id ? {title: 'Edit User', model: this.collection.get(id)} : {title: 'Add User'};
    console.log('options', options);
}
</code></pre>

<p>We don't have anywhere to send the user just yet, so we'll construct our options and log them to verify our event is wired in. Here we check for a <em>data-id</em> value on the element. If we have one, we are going to edit the user, so we set an appropriate title for our soon to be created dialog, and retrieve the user from the collection. If there is no <em>data-id</em>, like on the Add button, we set the title to 'Add User', and leave the model undefined. Reload your app and verify that we have all this working.</p>

<p><strong>Creating our Dialog</strong></p>

<p>Whether we are adding or editing a User, we will need a form with fields to enter data. Let's create a template for one, wrapped in the markup to create a Bootstrap modal dialog.</p>

<p><em>/app/users/single.hbs</em>  </p>

<pre><code class="language-markup">&lt;div class="modal-dialog"&gt;  
    &lt;div class="modal-content"&gt;
        &lt;div class="modal-header"&gt;
            &lt;button type="button" class="close" data-dismiss="modal" aria-hidden="true"&gt;×&lt;/button&gt;
            &lt;h4 class="modal-title"&gt;&lt;b&gt;{{title}}&lt;/b&gt;&lt;/h4&gt;
        &lt;/div&gt;
        &lt;div class="modal-body"&gt;
            &lt;form class="form-horizontal"&gt;
                &lt;div class="form-group"&gt;
                    &lt;label for="email" class="col-lg-2 control-label"&gt;Email&lt;/label&gt;

                    &lt;div class="col-lg-10"&gt;
                        &lt;input type="text" class="form-control" id="email" placeholder="Email"&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
                &lt;div class="form-group"&gt;
                    &lt;label for="name" class="col-lg-2 control-label"&gt;Name&lt;/label&gt;

                    &lt;div class="col-lg-10"&gt;
                        &lt;input type="text" class="form-control" id="name" placeholder="Name"&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
                &lt;div class="form-group"&gt;
                    &lt;label for="password" class="col-lg-2 control-label"&gt;Password&lt;/label&gt;

                    &lt;div class="col-lg-10"&gt;
                        &lt;input type="password" class="form-control" id="password" placeholder="Password"&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
            &lt;/form&gt;
        &lt;/div&gt;
        &lt;div class="modal-footer"&gt;
            &lt;button type="button" class="btn btn-default" data-dismiss="modal"&gt;Close&lt;/button&gt;
            &lt;button type="button" class="btn btn-primary js-saveUser"&gt;Save changes&lt;/button&gt;
        &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;  
</code></pre>

<p>This is mostly boilerplate Bootstrap code. Notice that we have assigned IDs to the form fields. We will use these to bind our data. Because we are binding our data, we don't need to use any template substitution for these values. We have also added a variable to hold our <em>title</em> at the top, and we added a <em>js-saveUser</em> class to our <strong>Save</strong> button. We'll use Bootstrap's built in functionality to cancel/close the modal when the user hits the Cancel or Close buttons.</p>

<p>To pair with our template, we will create a simple Backbone view. This view will handle binding our model data to the form fields and vice versa. It will also persist the data when the <strong>Save</strong> button is pressed.</p>

<p><em>/app/users/singleView.js</em>  </p>

<pre><code class="language-javascript">define(function (require) {

    'use strict';
    var Backbone = require('backbone');
    var mediator = require('mediator');
    var template = require('hbs!users/single');

    require('stickit');

    var User = require('users/model');

    return Backbone.View.extend({
        initialize: function (options) {
            this.title = options ? options.title : 'Please Set A Title';
            this.model = this.model || new User();
        },

        bindings: {
            '#name': 'name',
            '#email': 'email',
            '#password': 'password'
        },

        events: {
            'click .js-saveUser': 'saveUser'
        },

        render: function () {
            this.$el.html(template({title: this.title}));
            this.stickit();
            return this;
        },

        saveUser: function () {
            var self = this;
            this.model.save().done(function (response) {
                if (self.model.isNew()) {
                    self.model.set('_id', response._id);
                }
                mediator.trigger('users:userSaved', self.model);
            });
        }
    });

});
</code></pre>

<p>At the top, we require our dependencies. We also include <em>stickit</em> here. Since it is a plugin, we don't need to assign it to anything. In our <em>initialize</em> method, we set some default values if the options passed to us don't have them. We also create a new User if we need one, as is the case for when we are adding one.</p>

<p>The <em>bindings</em> block is new. This is how we configure <em>stickit</em>. In this simple example, we map our CSS selectors on the right to User model attributes on the left. Stickit can do a lot more than this so read the docs.</p>

<p>We set up a standard <em>events</em> entry to trap for the <strong>Save</strong> button.</p>

<p>In our <em>render</em> method, we render our template as normal, then call stickit to activate the bindings.</p>

<p>Finally, we create a <em>saveUser</em> method. We use Backbone's built in save functionality. This will determine if the User is new or being edited, and call the appropriate backend method. When we get a successful response, we update our object with an _id value if necessary, then fire off a message to let our list view know we are done. We do this so that the list view can manage the lifecycle of the dialog window, including the opening and closing of it.</p>

<p>Let's now go back to our list view and update it to manage the dialog window.</p>

<p>Add our new dependencies  </p>

<pre><code class="language-javascript">var mediator = require('mediator');  
var SingleView = require('users/singleView');  
require('bootstrap-modal');  
require('backbone.bootstrap-modal');  
</code></pre>

<p>Since we are going to be responding to message, let's wire that up:  </p>

<pre><code class="language-javascript">initialize: function(){  
    this.bindPageEvents();
},

bindPageEvents: function(){  
    mediator.on('users:userSaved', this.userSaved, this);
},

userSaved: function(user){  
    this.modal.close();
    this.collection.add(user);
    this.render();
}
</code></pre>

<p>When we receive a message that the user has been saved, we close the modal that we will soon create, add the passed user to our collection, and rerender the table. If the user has an id that is already part of our collection, it will update itself, otherwise it will add itself.</p>

<p>Finally, lets create the modal. Let's go back to our <em>editUser</em> method</p>

<pre><code class="language-javascript">editUser: function(e) {  
    var id = $(e.currentTarget).attr('data-id');
    var options = id ? {title: 'Edit User', model: this.collection.get(id)} : {title: 'Add User'};
    var modalView = new SingleView(options);
    this.modal = new Backbone.BootstrapModal({content: modalView}).open();
},
</code></pre>

<p>We've removed the logging. We instantiate the view that holds our form fields with the options we've created. We then wrap that view with a Backbone.BootstrapModal view and open it. Simple as that. Reload your app and try adding and editing some Users.</p>

<p>Let's make one final cosmetic tweak. Since the last column in the table is always the same visually, let's turn sorting off for it. Pass in the following options when we construct the DataTable</p>

<pre><code class="language-javascript">this.$('table').DataTable({  
    "aoColumns": [
        null,
        null,
        null,
        { "bSortable": false }
    ]
});
</code></pre>

<p><strong>Next Steps</strong></p>

<p>We now have a relatively full featured CRUD management tool. We could easily add new entities by following the patterns we have set up here. Could we have generated these much quicker with an all encompassing framework? Sure. The use of small focused plugins, however, has kept our boilerplate code to a minimum and we have had full control over every line of code.</p>

<p>The last big piece that we are going to add that I consider mandatory for a starter app is <strong>authentication</strong>. We will put all the User editing functionality behind a login screen and see how to hold and use application wide data, such as the currently logged in user.</p>

<p>(The code at this state in the project can be checked out at commit: <a href="https://github.com/bmajewski/relearning-backbone/commit/8a19651c576968b29f143d271147b0b288ca63a7">8a19651c576968b29f143d271147b0b288ca63a7</a>)</p>]]></content:encoded></item><item><title><![CDATA[(Re)Learning Backbone Part 4]]></title><description><![CDATA[<p><em>(Note: The code for this series is available on <a href="https://github.com/bmajewski/relearning-backbone">Github</a> - To get the code in preparation for this installment, checkout commit: <a href="https://github.com/bmajewski/relearning-backbone/commit/d82adb485a608278b2003415cab536503c40d5d2">d82adb485a608278b2003415cab536503c40d5d2</a>)</em></p>

<p><strong>Database Integration</strong></p>

<p>A lot of tutorials wave their hands at this point and assume you have a database connected. Worse, some will have you write stubs and</p>]]></description><link>http://brianmajewski.com/2015/02/19/relearning-backbone-part-4/</link><guid isPermaLink="false">6735c52a-db17-41c0-a71f-1fe0a8ccfa47</guid><category><![CDATA[javascript]]></category><category><![CDATA[mongodb]]></category><category><![CDATA[node]]></category><category><![CDATA[express]]></category><category><![CDATA[mongoose]]></category><category><![CDATA[postman]]></category><category><![CDATA[crud]]></category><dc:creator><![CDATA[Brian Majewski]]></dc:creator><pubDate>Fri, 20 Feb 2015 04:17:04 GMT</pubDate><media:content url="http://brianmajewski.com/content/images/2015/02/Mongoose_-PSF-.png" medium="image"/><content:encoded><![CDATA[<img src="http://brianmajewski.com/content/images/2015/02/Mongoose_-PSF-.png" alt="(Re)Learning Backbone Part 4"><p><em>(Note: The code for this series is available on <a href="https://github.com/bmajewski/relearning-backbone">Github</a> - To get the code in preparation for this installment, checkout commit: <a href="https://github.com/bmajewski/relearning-backbone/commit/d82adb485a608278b2003415cab536503c40d5d2">d82adb485a608278b2003415cab536503c40d5d2</a>)</em></p>

<p><strong>Database Integration</strong></p>

<p>A lot of tutorials wave their hands at this point and assume you have a database connected. Worse, some will have you write stubs and timeouts to simulate connection delays. If you know what you're doing, these can be a quick way to get a screen or feature running. If you're building from the ground up, you're just delaying the inevitable. Plus, if you've never done it before, figuring out how to wire it in later can be a challenge.</p>

<p><strong>MongoDB and mongoose</strong></p>

<p>Earlier in this series we installed <a href="http://www.mongodb.org/">MongoDB</a>. Ensure that you have a running copy before continuing. For a GUI front end, I like using <a href="https://github.com/jeromelebel/MongoHub-Mac">MongoHub</a>. <a href="http://mongoosejs.com/">Mongoose</a> is an object modeling solution that lets you write simple schema based objects to work between your Node server and your Mongo database. It has hooks for validation, query building and more, and with a healthy plugin ecosystem can do nearly anything you throw at it. We'll only scratch the surface of its feature set.</p>

<p>To install mongoose, run:</p>

<pre><code>npm install mongoose --save  
</code></pre>

<p>We'll need to tell our app how to connect to MongoDB. In our <code>server.js</code> file, add  </p>

<pre><code>var mongoose = require('mongoose');  
</code></pre>

<p>to the dependencies section at the top. Then underneath that, add  </p>

<pre><code>mongoose.connect('mongodb://localhost:27017/rlbb');  
</code></pre>

<p>If you configured MongoDB to run on another port, edit the above the string. <code>rlbb</code> is the name of our database and will be created if not present. Here is also where we would add things like database username, password, and the like if we had them.</p>

<p>Now, let's create a User model. Under <code>app/models</code>, create <code>user.js</code></p>

<pre><code class="language-javascript">var mongoose = require('mongoose');  
var Schema = mongoose.Schema;

var UserSchema = new Schema({  
    name: String,
    email: {type: String, required: true, index: {unique: true}},
    password: {type: String, required: true, select: false}
});

module.exports = mongoose.model('User', UserSchema);  
</code></pre>

<p>Here, we've pulled in our mongoose dependency and created a User Schema object. Mongoose uses the Schema as representation of a MongoDB collection and the base of its functionality. We've defined a <strong>name</strong>, an <strong>email</strong>, and a <strong>password</strong>. Along with the property names, we've defined their <em>SchemaType</em>, in this case, they are all Strings. For email and password, we've also included some additional properties. <em>required</em> indicates that the field must be present to be valid. Other validators include <em>min</em>, <em>max</em>, <em>match</em>, and custom validators can be created. For email, which we will use as our username, we create an index for it, and put a <em>unique</em> constraint on it. For password, we indicate that normal retrieval of this object from the collection should <em>not</em> include the password field. This prevents it from going across the network. When we add authentication later, we will explicitly ask for the password. Finally, we create a mongoose model from the schema and export it.</p>

<p><strong>Our First REST Endpoints</strong></p>

<p>So, we have a model of our User data. We now need a way to retrieve it from and write it to the database. In this app, all of our API URLs will start with <code>/api/</code> and then follow with the appropriate REST endpoints. For user, we will end up creating:  </p>

<dl>  
    <dt>/api/users</dt>
    <dd>POST - With a POST request, a new user will be created.<br>
    GET - With a GET request, this will return all users.
    </dd>

    <dt>/api/users/:user_id</dt>
    <dd>GET - With a GET request, this will return a single user with an ID that matches <i>:user_id</i>.<br>
    PUT - With a PUT request, the user indicated will be updated.<br>
    DELETE - With a DELETE request, the user indicated will be deleted.</dd>
</dl>

<p>With just two endpoints, and using the HTTP verbs, we can satisfy our basic CRUD requirements. To define these, we will create an Express router and then have Express <em>use</em> it, much like we did with the static assets directory and the catch all request handler.</p>

<p>Under <code>app/routes</code>, create <code>user.js</code> <sup id="fnref:1"><a href="http://brianmajewski.com/2015/02/19/relearning-backbone-part-4/#fn:1" rel="footnote">1</a></sup>.</p>

<pre><code class="language-javascript">var bodyParser = require('body-parser');  
var User = require('../models/user');

module.exports = function (app, express) {  
    var userRouter = express.Router();

    userRouter.get('/', function (req, res) {
        res.json({message: 'api is loaded'});
    });

    userRouter.route('/users')
        .post(function (req, res) {
            var user = new User();
            user.name = req.body.name;
            user.username = req.body.username;
            user.password = req.body.password;

            user.save(function (err) {
                if (err) {
                    if (err.code === 11000) {
                        return res.json({success: false, message: 'Duplicate username.'});
                    } else {
                        return res.send(err);
                    }
                } else {
                    res.json({message: 'user created'});
                }

            });
        })
        .get(function (req, res) {
            User.find(function (err, users) {
                if (err) {
                    res.send(err);
                }
                res.json(users);
            })
        });

    userRouter.route('/users/:user_id')
        .get(function (req, res) {
            User.findById(req.params.user_id, function (err, user) {
                if (err) res.send(err);
                res.json(user);
            })
        })
        .put(function (req, res) {
            User.findById(req.params.user_id, function (err, user) {
                if (err) res.send(err);

                if (req.body.name) user.name = req.body.name;
                if (req.body.email) user.email = req.body.email;
                if (req.body.password) user.password = req.body.password;

                user.save(function (err) {
                    if (err)res.send(err);
                    res.json({message: 'user updated'});
                });
            });
        })
        .delete(function (req, res) {
            User.remove({_id: req.params.user_id}, function (err, user) {
                if (err) res.send(err);
                res.json({message: 'user deleted'});
            })
        });

    return userRouter;
};
</code></pre>

<p>This looks like a lot, but it's fairly straightforward. Let's tackle it a chunk at a time.</p>

<pre><code class="language-javascript">var bodyParser = require('body-parser');  
var User = require('../models/user');  
</code></pre>

<p>Here will pull in our dependencies. We will use <em>body-parser</em> to get the data that comes with the PUT and POST requests and <em>User</em> is the user model we just created.</p>

<pre><code class="language-javascript">    var userRouter = express.Router();

    userRouter.get('/', function (req, res) {
        res.json({message: 'api is loaded'});
    });
</code></pre>

<p>Here we create an instance of an Express router. To give us a way to verify our routes have been initialized properly, we create a default route <code>api/</code> that will respond with a canned message. If there are problems we can use this to see if it is a server or database issue.</p>

<pre><code class="language-javascript">userRouter.route('/users')  
        .post(function (req, res) {
            var user = new User();
            user.name = req.body.name;
            user.email = req.body.email;
            user.password = req.body.password;

            user.save(function (err) {
                if (err) {
                    if (err.code === 11000) {
                        return res.json({success: false, message: 'Duplicate username.'});
                    } else {
                        return res.send(err);
                    }
                } else {
                    res.json({message: 'user created'});
                }

            });
        })
        .get(function (req, res) {
            User.find(function (err, users) {
                if (err) {
                    res.send(err);
                }
                res.json(users);
            })
        });
</code></pre>

<p>Here we create the <code>api/users</code> route and handle both the POST and the GET cases. In the POST block, we create a new User, set the fields with data from the request body, and save it. Mongoose handles the heavy lifting of creating the query and talking to the database. We perform some basic error-handling, and return an appropriate message to the client.</p>

<p>In the GET block, we call a static model method on User to retrieve all the stored users and return them. Once again, mongoose takes care of the details.</p>

<pre><code class="language-javascript">userRouter.route('/users/:user_id')  
        .get(function (req, res) {
            User.findById(req.params.user_id, function (err, user) {
                if (err) res.send(err);
                res.json(user);
            })
        })
        .put(function (req, res) {
            User.findById(req.params.user_id, function (err, user) {
                if (err) res.send(err);

                if (req.body.name) user.name = req.body.name;
                if (req.body.username) user.username = req.body.username;
                if (req.body.password) user.password = req.body.password;

                user.save(function (err) {
                    if (err)res.send(err);
                    res.json({message: 'user updated'});
                });
            });
        })
        .delete(function (req, res) {
            User.remove({_id: req.params.user_id}, function (err, user) {
                if (err) res.send(err);
                res.json({message: 'user deleted'});
            })
        });
</code></pre>

<p>Here we create the <code>api/users/:user_id</code> route. Express will take the value in the request that maps to the <code>:user_id</code> section and create a request parameter that we can use. In the GET block, we use mongoose's <em>findById</em> method to retrieve a specific user. In the PUT block, we again retrieve the requested user, update its information with data from the request body, then save it. Finally, in the DELETE block, we use mongoose's <em>remove</em> function to delete the specified user.</p>

<p>Now it's time to wire the router into the server. In <code>server.js</code>, <strong>after</strong> the static directory declaration, add the following</p>

<pre><code class="language-javascript">// already in our file
app.use(express.static(__dirname + '/public'));

// ADD THESE TWO LINES
var userRoutes = require('./app/routes/user')(app, express);  
app.use('/api', userRoutes);

// already in our file
app.get('*', function(req,res){  
    res.sendFile(path.join(__dirname + '/public/index.html'));
});
</code></pre>

<p>First we create the routes, by requiring the file and passing it the two needed fields, app and express. (Go back and look at how we declared our router definition and you will see we have these two params listed). Then, we tell our server to <em>use</em> the routes. Remember, order is important. First our static files, then our API routes, and finally the catch all to serve up our home page. If we added our routes after the catch all, they would never be hit.</p>

<p>If we were to run our server now, with <code>nodemon server.js</code> we would be able to get and set users via HTTP. But... we don't have any users yet, and we don't have screens to input data. Any easy solution is to use something like <a href="https://chrome.google.com/webstore/detail/postman-rest-client/fdmmgilgnpjigdojojpjoooidkmcomcm/related?hl=en">Postman - REST Client for Chrome</a> (all the browsers have similar tools). In the URL field, enter <code>localhost:1337/api</code> and make sure GET is selected in the dropdown. When you hit send, you should see our test message returned in JSON format. </p>

<p>We can do a similar task to add a user. Set the URL to <code>localhost:1337/api/users</code>, the method to POST, select <code>raw</code> for our input data and add</p>

<pre><code>{ "email" : "hireme@brianmajewski.com", name: "Brian M", password: "123456Secure!"}
</code></pre>

<p>These are the fields we defined on our User model.</p>

<p>We also need to set our content type, so select Headers, and for name put <code>Content-Type</code> and value put <code>application/json</code>. If we're configured right, you should get a response back saying user created. To see our new user, hit the same URL, with GET, and you should receive a response similar to</p>

<pre><code>[
    {
        "_id": "54e6b162eb2ac61c54e9b80f",
        "email": "hireme@brianmajewski.com",
        "name": "Brian M",
        "__v": 0
    }
]
</code></pre>

<p>Notice: Our password is not returned, as we specified in our schema. Experiment with the other routes and verify that you can update and delete users as well.</p>

<p>So there you have the basics for all CRUD operations for your app. Whether you are storing Widgets, Gizmos, Comments, or Reviews, you will follow the same basic pattern. Later, when we add authentication, you'll see how we can enhance mongoose's standard methods to perform extra functionality, such as encrypting the password, before saving the user.</p>

<p>To get the code with these updates checkout commit <a href="https://github.com/bmajewski/relearning-backbone/commit/18b0d51ee45d966abf9293be9a5fe25c6af8c6a6">18b0d51ee45d966abf9293be9a5fe25c6af8c6a6</a></p>

<p><strong>Next Steps</strong></p>

<p>With a functional backend in place, we will begin to create our front end web application. We'll look at using Bower to manage dependencies and RequireJS to load modules.</p>

<p>(<strong>UPDATE</strong>: There was a bug in the PUT block of the /users/:user_id route - <em>username</em> should have been <em>email</em> - This bug was fixed in the Chapter 7 version of the code on Github and in the text above)</p>

<div class="footnotes"><ol>  
    <li class="footnote" id="fn:1">
        <p>Some people prefer to include the function in the name, such as userModel.js and userRoute.js. I go back and forth on this. They are namespaced by their directory structure, so if there is no chance I am going to get them confused, I'll shorten them like I did here. You can name them mickey, pluto, and goofy if that floats your boat. I prefer frameworks without magic naming conventions.<a href="http://brianmajewski.com/2015/02/19/relearning-backbone-part-4/#fnref:1" title="return to article"> ↩</a></p><p>
    </p></li>
    </ol></div>]]></content:encoded></item><item><title><![CDATA[(Re)Learning Backbone Part 3]]></title><description><![CDATA[<p><strong>Project Structure</strong></p>

<p>We are going to start with a simple barebones structure to start with. In your project directory create both an <code>app</code> and a <code>public</code> directory. Under, <code>public</code>, create <code>assets</code>. And we're done. We'll add more as we flesh out the app. I like working iteratively, adding what we</p>]]></description><link>http://brianmajewski.com/2015/02/15/relearning-backbone-part-3/</link><guid isPermaLink="false">d22b402c-21a2-4fb1-81a8-25b81e6e0c73</guid><category><![CDATA[backbone]]></category><category><![CDATA[javascript]]></category><category><![CDATA[node]]></category><category><![CDATA[npm]]></category><category><![CDATA[express]]></category><category><![CDATA[nodemon]]></category><dc:creator><![CDATA[Brian Majewski]]></dc:creator><pubDate>Sun, 15 Feb 2015 20:30:19 GMT</pubDate><media:content url="http://brianmajewski.com/content/images/2015/02/p1010298--2-.jpg" medium="image"/><content:encoded><![CDATA[<img src="http://brianmajewski.com/content/images/2015/02/p1010298--2-.jpg" alt="(Re)Learning Backbone Part 3"><p><strong>Project Structure</strong></p>

<p>We are going to start with a simple barebones structure to start with. In your project directory create both an <code>app</code> and a <code>public</code> directory. Under, <code>public</code>, create <code>assets</code>. And we're done. We'll add more as we flesh out the app. I like working iteratively, adding what we need when we need it. Remember, it's <em>software</em> - we can change it if we want to.</p>

<p><img src="http://brianmajewski.com/content/images/2015/02/Screen-Shot-2015-02-15-at-11-38-14-AM.png" alt="(Re)Learning Backbone Part 3"></p>

<p><strong>NPM (Node Package Manager)</strong></p>

<p>To manage our server side dependencies, we are going to use Node's built-in package manager <a href="https://www.npmjs.com/">NPM</a>. To start, we need a <code>package.json</code> file. You can read the docs and create one by hand or you can use the tool to create one. Run  </p>

<pre><code>npm init</code></pre>

<p>in the root of your project, answer the questions, <em>et voila</em>, you should have a <code>package.json</code> file that looks something like this:</p>

<p><img src="http://brianmajewski.com/content/images/2015/02/Screen-Shot-2015-02-15-at-11-48-58-AM.png" alt="(Re)Learning Backbone Part 3"></p>

<p>If you entered something other than <code>server.js</code> for the <em>main</em> value (and you probably did, since it isn't the default), go ahead and edit the contents. <code>server.js</code> will be the main file we run to launch our web server and serve up data.</p>

<p>For our barebones server, we are going to use the following node packages: <a href="http://expressjs.com/">express</a>, <a href="https://www.npmjs.com/package/body-parser">body-parser</a>, <a href="https://www.npmjs.com/package/morgan">morgan</a>, and live</p>

<dl>  
<dt>express</dt>  
<dd>will provide nearly all of the web server functionality along with the middleware we will need to do authentication.</dd>  
<dt>body-parser</dt>  
<dd>will allow us to read json from incoming request</dd>  
<dt>morgan</dt>  
<dd>will let us log incoming requests</dd>  
</dl>

<p>Learning how to use Express would be a lesson in itself and you should dig into their documentation as needed.</p>

<p>To install these, run  </p>

<pre><code>npm install express body-parser morgan --save</code></pre>

<p>from your project root. It will download the packages, and their dependencies, and save the information to your package.json file.</p>

<p>One last package we want to download is <a href="https://www.npmjs.com/package/nodemon">nodemon</a>. When our server is running, this will watch for any changes and restart the server automatically as needed. We need to install this globally, so run:</p>

<pre><code>npm install -g nodemon</code></pre>

<p><strong>server.js</strong></p>

<p>This will be the heart of our web server.</p>

<pre><code class="language-javascript">var express = require('express');  
var bodyParser = require('body-parser');  
var morgan = require('morgan');

var path = require('path');

var app = express();

// Sets us up to read body content from POST requests
app.use(bodyParser.urlencoded({extended: true}));  
app.use(bodyParser.json());

// Adds request logging
app.use(morgan('dev'));

// Sets up the server to serve static files from the public directory
app.use(express.static(__dirname + '/public'));

// For all requests we do not explicitly handle (*), return index.html
app.get('*', function(req,res){  
    res.sendFile(path.join(__dirname + '/public/index.html'));
});


// Listen on port 1337
var port = 1337;  
app.listen(port);  
console.log('Server up and running on port ' + port);  
</code></pre>

<p>So, what's going on here? </p>

<ul>
<li>First we define our dependencies and create an <code>app</code> variable to represent the application/server.</li>
<li>Then, we use the <em>body-parser</em> package to tell our app how to get JSON from the body of incoming requests. </li>
<li>We activate <em>morgan</em> in dev mode, which will log our requests.</li>
<li>We define a directory to serve up static resources like html, css, fonts, etc. <code>__dirname</code> is provided by the <em>path</em> package.</li>
<li>Finally, for all incoming requests that have not been handled yet(<code>*</code>), we return <code>index.html</code>. So, if we ask for a specific CSS file, the static instruction above will handle it. If we ask for an HTML page that doesn't exist, this instruction will handle it. We will be adding more routes and instructions as we go on. As you can see, the order in which we define these routes is important. Express will go through each one until it comes to a handler that satisifes the request. This is a classic implementation of the <a href="http://en.wikipedia.org/wiki/Chain-of-responsibility_pattern">chain of responsibility</a> pattern.</li>
</ul>

<p>That's it. That's all you need to have a basic web server. We could have left out the body-parser section for an even leaner file, but we will need it next. Run  </p>

<pre><code>nodemon server.js</code></pre>

<p>and you should see output similar to: <br>
<img src="http://brianmajewski.com/content/images/2015/02/Screen-Shot-2015-02-15-at-12-19-18-PM.png" alt="(Re)Learning Backbone Part 3"></p>

<p>We can create a simple <code>index.html</code> file in our public directory and view it in a browser. To ensure that static files are being served up as well, create a <code>css</code> folder under <code>assets</code> and add a <code>styles.css</code> file.</p>

<p><em>Sample HTML</em>  </p>

<pre><code class="language-markup">&lt;!DOCTYPE html&gt;  
&lt;html&gt;  
&lt;head lang="en"&gt;  
    &lt;base href="/"&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;title&gt;Relearning Backbone&lt;/title&gt;
    &lt;link rel="stylesheet" href="assets/css/styles.css"&gt;
&lt;/head&gt;  
&lt;body&gt;  
&lt;h3&gt;Relearning Backbone&lt;/h3&gt;  
&lt;/body&gt;  
&lt;/html&gt;  
</code></pre>

<p><em>Sample CSS</em>  </p>

<pre><code class="language-css">h3 {  
    color: #4169e1;
}
</code></pre>

<p><strong>Next Steps</strong></p>

<p>Next time, we are going to add a database connection to the server, and some User entities to it.</p>]]></content:encoded></item><item><title><![CDATA[(Re)Learning Backbone Part 2]]></title><description><![CDATA[<blockquote>
  <p>Opinions are like birthdays: everyone has one and I heard about yours on Facebook.</p>
</blockquote>

<p><strong>Tool Sets and Libraries</strong></p>

<p>This is easily the most opinionated part of this process. I am always open to code changes; hearing the viewpoints of other developers who may have more experience or a different perspective</p>]]></description><link>http://brianmajewski.com/2015/02/13/relearning-backbone-part-2/</link><guid isPermaLink="false">7625c66a-c76c-42cd-9b86-2f382fbdbb44</guid><category><![CDATA[backbone]]></category><category><![CDATA[javascript]]></category><category><![CDATA[intellij]]></category><category><![CDATA[mongodb]]></category><category><![CDATA[node]]></category><category><![CDATA[brew]]></category><category><![CDATA[mac]]></category><dc:creator><![CDATA[Brian Majewski]]></dc:creator><pubDate>Fri, 13 Feb 2015 16:36:57 GMT</pubDate><media:content url="http://brianmajewski.com/content/images/2015/02/construction408661.jpg" medium="image"/><content:encoded><![CDATA[<blockquote>
  <img src="http://brianmajewski.com/content/images/2015/02/construction408661.jpg" alt="(Re)Learning Backbone Part 2"><p>Opinions are like birthdays: everyone has one and I heard about yours on Facebook.</p>
</blockquote>

<p><strong>Tool Sets and Libraries</strong></p>

<p>This is easily the most opinionated part of this process. I am always open to code changes; hearing the viewpoints of other developers who may have more experience or a different perspective often lead me to change my code. We call it <em>software</em> for a reason. It should be malleable. It should adapt. When it comes to my tools, however, that's a different story.</p>

<p><strong>OS - Mac OS X</strong></p>

<p>Let's get the holy war out of the way. If you use Windows, more power to you. You must like the extra challenges of playing on <em>Expert</em> mode. For me, there are three key reasons I develop on the Mac.</p>

<dl>  
<dt>Environment</dt>  
<dd>Most every environment I am going to deploy to is a *nix variant. Having a BASH (or similar) shell integrated into the OS allows me to create workflows that work everywhere I do.</dd>  
<dt>The Cool Kids Use It</dt>  
<dd>Most of the developers and designers that I read and learn from are using it. This isn't simply a case of "me too!" This is a case where I want zero impediments in my way of completing my task. If they recommend a tool or a library or even some non-web-dev related utility, I'd rather be able to copy them than go searching for an equivalent.</dd>  
<dt>Comfort</dt>  
<dd>I've worked on Apple hardware since the Apple][ days. It just makes more sense to me.</dd>  
</dl>

<p>So, yeah, use Windows if you want. Good luck with that.</p>

<p><strong>IDE - Jetbrains IntelliJ IDEA (or Webstorm)</strong></p>

<p>I'm maybe a little bit more flexible on this issue, but not by much. As a professional developer who works with a number of different languages and technologies, having a tool that works across all of them is something I find is worth my investment in time and money. I've been using it since Version 1 when I met the original developers at a conference in Prague. It has been my <a href="https://www.jetbrains.com/idea/">IDE of choice</a> ever since. Any good text editor like <a href="http://www.sublimetext.com/">Sublime</a> or <a href="https://atom.io/">Atom</a> can be a useful tool with the right setup and plugins. IDEA mostly works out of the box with deep support for things like Node, Angular, Grunt, and the like.</p>

<p><strong>Brew</strong></p>

<p><a href="http://brew.sh/">Brew</a> is "The missing package manager for OS X" and allows you to install and maintain the tools used to develop and build. Get it. Install it. If you like GUIs, get <a href="https://www.cakebrew.com/">Cakebrew</a>.</p>

<p><strong>Node</strong></p>

<p>We're going to use <a href="http://nodejs.org/">Node</a> to stand up a web server to serve our REST endpoints and access the database. <strong>DO NOT</strong> simply go to the website, download the package and install it. You'll end up in a world of hurt, having to run everything as <em>sudo</em>. Use Brew (see above). <code>$ brew install node</code>  Should we switch over to <a href="https://iojs.org/en/index.html">io.js</a>? Maybe? This is one of those rat holes I wanted to avoid with this project. Investigating io.js is an endeavor for another day.</p>

<p><strong>MongoDB</strong></p>

<p>Is <a href="http://www.mongodb.org/">MongoDB</a> the right database for your application? Who knows? For this project, we want a simple document datastore that has some easy integration with javascript. We could serve up JSON files instead of hitting a datastore, but that doesn't meet the requirements of having a fully functional application from soup to nuts to build off. We can always swap it out for another technology. Again, use Brew to install it.</p>

<p><strong>Next Steps</strong></p>

<p>At this point, we have the makings for a web server that can serve up data. Well, we have the tools anyways. In the next installment, we'll create a project structure and web server we'll use throughout the project.</p>]]></content:encoded></item></channel></rss>