Helpers for reusable code

So far, each of the pages that we have rendered display their viewModel data perfectly, but that pesky sidebar still remains blank. We're going to fix this by creating a few modules for the sidebar content by implementing them as helper modules. These helper modules will be used repeatedly by various parts of our application and don't necessarily belong to the controller folder or the server folder. So, we'll just create a new home called helpers and store these modules there.

Note

As we are just loading temporary fixture data into our view models, the data we set up in the helpers as well as the controllers will all be replaced with actual live data in the next chapter once we implement MongoDB.

The sidebar module

First, we will create a module for the entire sidebar. This module will be responsible for calling multiple other modules to populate viewModel for each section of the sidebar. As we are going to be populating each page's own viewModel with data specifically for the sidebar, the sidebar module's function will accept that original viewModel as a parameter. This is so that we can append data to the existing viewModel for each page.

Here, we will be appending a sidebar property (which is a JavaScript object) that contains properties for each of the sections of the sidebar.

To get started, first create a file named helpers/sidebar.js and insert the following code:

var Stats = require('./stats'),
    Images = require('./images'),
    Comments = require('./comments');

module.exports = function(viewModel, callback){
    viewModel.sidebar = {
        stats: Stats(),
        popular: Images.popular(),
        comments: Comments.newest()
    };

    callback(viewModel);
};

In the preceding code, you can see that we first required a module for each section of the sidebar. The existing viewModel for any given page that displays the sidebar is the first parameter of the function. We add a sidebar property to viewModel and set values for each property by calling the module for each section of the sidebar. Finally, we execute a callback that was passed in as the second parameter to the sidebar module. This callback is an anonymous function that we will use to execute the rendering of the HTML page.

Let's update the home and image controllers to include a call to the sidebar module as well as defer rendering the HTML template for each page to the callback for the sidebar module.

Edit controllers/home.js and take the following line of code:

res.render('index', viewModel);

Replace it with this new block of code:

sidebar(viewModel, function(viewModel) {
    res.render('index', viewModel);
});

Make the exact same changes to the controllers/image.js file replacing index with image:

sidebar(viewModel,function(viewModel){
res.render('image', viewModel);
});

Again, notice how we execute the sidebar module and pass the existing viewModel as the first parameter and a basic anonymous function as a callback for the second parameter. What this is doing is waiting to render the HTML for the view until after the sidebar has completed populating viewModel. This is because of the asynchronous nature of Node.js. Suppose we wrote the code in the following way instead:

sidebar(viewModel);
res.render('index', viewModel);

Here, it's quite likely that the res.render statement will execute before sidebar has even finished doing any work. This is going to become very important once we introduce MongoDB in the next chapter.

Additionally, as we are now using the sidebar module in each controller, be sure to require it at the top of both controllers by including the following code:

var sidebar = require('../helpers/sidebar');

Now that our sidebar module is complete, and it's being called from both controllers, let's complete the sidebar by creating each of the submodules that are required.

The stats module

The stats module is going to display a few random pieces of statistics about our app. Specifically, it will show the count for the total number of images, comments, views, and likes for the entire website.

Create the helpers/stats.js file and insert the following code:

module.exports = function() {
    var stats = {
        images:     0,
        comments:   0,
        views:      0,
        likes:      0
    };

    return stats;
};

This module is pretty basic and all it does is create a standard JavaScript object with a few properties for the various stats, each set initially to 0.

The images module

The images module is responsible for returning various collections of images. Initially, we will create a popular function that will be used to return a collection of the most popular images on the website. Initially, this collection will simply be an array of image objects with the sample fixture data present.

Create the helpers/images.js file and insert the following code:

module.exports = {
    popular: function() {
        var images = [
            {
                uniqueId:       1,
                title:          'Sample Image 1',
                description:    '',
                filename:       'sample1.jpg',
                views:          0,
                likes:          0,
                timestamp:      Date.now()
            }, {
                uniqueId:       2,
                title:          'Sample Image 2',
                description:    '',
                filename:       'sample2.jpg',
                views:          0,
                likes:          0,
                timestamp:      Date.now()
            }, {
                uniqueId:       3,
                title:          'Sample Image 3',
                description:    '',
                filename:       'sample3.jpg',
                views:          0,
                likes:          0,
                timestamp:      Date.now()
            }, {
                uniqueId:       4,
                title:          'Sample Image 4',
                description:    '',
                filename:       'sample4.jpg',
                views:          0,
                likes:          0,
                timestamp:      Date.now()
            }
        ];
        return images;
    }
};

The comments module

Similar to the image's helper module, the comments module will return a collection of the newest comments posted to the site. The idea of particular interest is that each comment also has an image attached to it so that the actual image for each comment can be displayed as a thumbnail while displaying the list of comments (otherwise, we lose context when we see a random list of comments with no related image).

Create the helpers/comments.js file and insert the following code:

module.exports = {
    newest: function() {
        var comments = [
            {
               image_id:   1,
               email:     '[email protected]',
               name:      'Test Tester',
               gravatar:  'http://lorempixel.com/75/75/animals/1',
               comment:   'This is a test comment...',
               timestamp:  Date.now(),
               image: {
                    uniqueId:       1,
                    title:          'Sample Image 1',
                    description:    '',
                    filename:       'sample1.jpg',
                    views:          0,
                    likes:          0,
                    timestamp:      Date.now
                }
            }, {
               image_id:   1,
               email:     '[email protected]',
               name:       Test Tester',
               gravatar:  'http://lorempixel.com/75/75/animals/2',
               comment:   'Another followup comment!',
               timestamp:  Date.now(),
                image: {
                     uniqueId:       1,
                     title:          'Sample Image 1',
                     description:    '',
                     filename:       'sample1.jpg',
                     views:          0,
                     likes:          0,
                     timestamp:      Date.now
                }
            }
        ];

        return comments;
    }
};

Again, this is just a basic JavaScript array of objects with a few properties for each comment, one of which is an actual image and its properties (the image property should look familiar since it's the same as one of the items in the images helper module).

Testing the sidebar implementation

Now that our sidebar module is complete along with its dependent submodules for the various stats, images, and comments, it's time to give our application another test run. Launch the node server and open the application in your browser.

You should now see the sidebar complete with content on both the homepage as well as the image landing page.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.225.175.151