Using Socket IO Loading data from MongoDB and Express js
As we are now able to send static data to our client with Socket.IO, we have all the tools we need to send dynamic data as well. MongoDB is a NoSQL database that stores data as JSON documents. In this recipe, we will send data from our database to the client side to get rendered.
Getting ready
Before you begin, you will need to install MongoDB on your machine. MongoDB can be installed by navigating to https://www.mongodb.org and following the installation steps there. Once MongoDB is installed, you can start the MongoDB server by entering mongod
on your terminal window. Leave the mongod
process running; you'll need to have it available to access your database.
You will also have to install a Node adapter for MongoDB. We will use Mongoose. This can be installed from NPM by entering npm install mongoose
on your terminal.
How to do it…
To send dynamic data from a MongoDB database via Socket.IO, follow these steps:
First, we will create a
server.js
file. This will be the file that starts the server and loads all of our server-side dependencies:var express = require('express'), app = express(), http = require('http'), socketIO = require('socket.io'), server, io; app.get('/', function (req, res) { res.sendFile(__dirname + '/index.html'); }); server = http.Server(app); server.listen(5000); io = socketIO(server); io.on('connection', function (socket) { var controllers = ['comments', 'posts']; for (var i = 0; i < controllers.length; i++) { require('./controllers/' + controllers[i] + '.controller')(socket); } });
We will import a file from
lib/mongo.js
. This file will simply connect to a MongoDB database and export themongoose
instance for us to use throughout the app.var mongoose = require('mongoose'); mongoose.connect('mongodb://localhost/dashboard'); module.exports = mongoose;
Now, we will need to include a MongoDB model for our comments. This can go in
models
/comment.js
. This file will be responsible for creating a schema for our model and then returning the model itself, as shown in the following code:var mongoose = require('../lib/mongo'); var commentSchema = mongoose.Schema({ user: String, comment: String }); module.exports = mongoose.model('Comment', commentSchema);
Now that we have a comments model, we can access it in our
controllers
/comments.controller.js
file with the following code:var Comment = require('../models/comment'); module.exports = function (socket) { var stream = Comment.find().stream(); stream.on('data', function (comment) { socket.emit('comment.add', comment); }); };
Then, we need to create our
index.html
template. This will listen for any new comments from the server and append them to the DOM, as shown in the following code:<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" /> <div class="container"> <div class="row"> <div class="col-md-12"> <h3 class="text-primary">Recent Comments</h3> <table class="table"> <thead> <tr> <th>User</th> <th>Comment</th> </tr> </thead> <tbody id="recent-comments"> <!-- Recent Comments --> </tbody> </table> </div> <div> </div> <script src="http://code.jquery.com/jquery-2.1.4.min.js"></script> <script src="/socket.io/socket.io.js"></script> <script> var socket = io('http://localhost:5000'); // Add a comment socket.on('comment.add', function (data) { var $row = $('<tr>' + '<td>' + data.user + '</td>' + '<td>' + data.comment + '</td>' + '</tr>'); $('#recent-comments').append($row); }); </script>
Finally, we need to display data in our dashboard. We can create a
lib
/seed.js
file to handle seeding and call it by running nodelib
/seed
on the terminal:var Comment = require('../models/comment'); // New comments var comments = [{ user: 'Batman', comment: 'Great post!' }, { user: 'Robin', comment: 'Interesting ideas...' }, { user: 'Joker', comment: 'Thanks, Batman!' }, { user: 'Bruce Wayne', comment: 'I agree with Batman' }]; // Loop over new comments and create them for (var i = 0; i < comments.length; i++) { new Comment(comments[i]).save(); } console.log('Database Seeded'); process.exit(0);
How it works…
We will use the Mongoose stream method in our controller by calling Comment.find().stream()
. Using the stream method, we will be able to pipe our comments to Socket.IO one by one as and when they are available.
What we are doing is not much different from just piping in static data. The only difference is that we are listening to the database stream to pipe the data from.