Simple Chat App using NodeJS and MongoDB Atlas Part 3

Introduction

In the previous article, we show you how to create a MongoDB Atlas free tier, a user for the cluster and configured the network access and added our IP address in the whitelisted IPs. In this section, we will dive into coding the rest of our chat application while interacting with the MongoDB Atlas database.

Prerequisites

  • Ensure to finish other parts of this series.

Coding The Server.js

In this section, we will be showing the code of the server.js and discuss the code part by part.

Including Necessary Modules in Node.Js

The below block of codes was the basic form on how to include modules in Node.js and how to invoke them.

var express = require("express");
var app = express();
var http = require("http").Server(app);
var io = require("socket.io")(http);

var bodyParser = require("body-parser");
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

var mongoose = require("mongoose");
var Message = mongoose.model("message", {
  name: String,
  message: String
});

app.use(express.static(__dirname));

var dbUrl =
  "mongodb+srv://user:1234@cluster0-bcwfr.mongodb.net/test?retryWrites=true&w=majority";

Let’s discuss the above code part by part.

  • The var express = require('express') simply requires express in our application

  • Then we set the express object to a variable named app using this code var app = express()

  • The var http = require('http').Server(app) allows us to setup a regular http server using the HTTP library from Node, then we pass in our Express variable app.

  • var io = require('socket.io')(http) we create a variable io then set it to require socket.io then pass a reference to http. Now this finally setup socket.io on the backend.

  • var bodyParser = require('body-parser') allows us to access body-parser in our code. Then we can use body-parser with the following code:

    • app.use(bodyParser.json()), this allows us to parse json type data
    • app.use(bodyParser.urlencoded({extended: false})), this allows the parsing urlencoded data.
  • app.use(express.static(__dirname)), This allows us to serve a static file from the entire directory (__dirname).

  • var mongoose = require('mongoose'), This includes the mongoose module in our code that we can reference when we create a model using the following code. `js var Message = mongoose.model(“message”, { name: String, message: String }); `

  • var dbUrl = 'mongodb+srv://user:1234@cluster0-bcwfr.mongodb.net/test?retryWrites=true&w=majority', This creates a reference to our MongoDB Atlas connection string.

Coding the Functions

This section shows the coding of the functions that we will be using for our server.js.

app.get("/messages", (req, res) => {
  Message.find({}, (err, messages) => {
    res.send(messages);
  });
});
  • The above code will add a route endpoint to our application via /messages and also tells that we will be handling GET request with the help of the app.get() function. We provide a callback that takes a request (req) and a reference to a response (res).
app.post("/messages", async (req, res) => {
  try {
    var message = new Message(req.body);
    var savedMessage = await message.save();
    console.log("saved");
    var censored = await Message.findOne({ message: "badword" });

    if (censored) await Message.remove({ _id: censored.id });
    else io.emit("message", req.body);
    res.sendStatus(200);
  } catch (error) {
    res.sendStatus(500);
    return console.error(error);
  } finally {
    console.log("message post called");
  }
});
  • The above code handles the POST method of our application.

  • We make our express function synchronous by specifying async within our code app.post('/messages', async (req, res), this returns a value once it finishes and will be saved in variable savedMessage (var savedMessage = await message.save()).

  • We implement a simple word censor using the following command.

var censored = await Message.findOne({ message: "notnice" });
if (censored) await Message.remove({ _id: censored.id });
else io.emit("message", req.body);
res.sendStatus(200);
  • What the code does, is that it removes the word having the censored word ‘notnice’ or any word you can use here. Then it emits the new message (if there’s any) via code io.emit('message',req.body) and send a 200 status.

  • Notice that we use the generic try/catch block for basic error handling and also the finally method to be executed regardless if the try/catch block fails or not.

io.on("connection", socket => {
  console.log("a user has been connected");
});
  • This code creates a notification in our console if the new user connected to the server.
mongoose.connect(
  dbUrl,
  { useNewUrlParser: true, useUnifiedTopology: true },
  err => {
    console.log("mongo db connection", err);
  }
);
  • This code connects to our database via mongoose, and display a notification once connected or throw an error.
var server = http.listen(2500, () => {
  // we use the 'server.address().port' to reference the actual port
  // so this part of the code will update its value whenever we change the port of the server
  console.log("server is listening on port", server.address().port);
});
  • We use the http so that both Express and socket.io

Conclusion

In this article we show you how to code our server.js file, in the next article we will show you and discuss how to code the frontend of our application using the index.html file.

The Code

Below is the entire code for our server.js.

var express = require("express");
var app = express();
var http = require("http").Server(app);
var io = require("socket.io")(http);
var bodyParser = require("body-parser");
var mongoose = require("mongoose");
app.use(express.static(__dirname));

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
var dbUrl =
  "mongodb+srv://user:1234@cluster0-bcwfr.mongodb.net/test?retryWrites=true&w=majority";
var Message = mongoose.model("message", {
  name: String,
  message: String
});

app.get("/messages", (req, res) => {
  Message.find({}, (err, messages) => {
    res.send(messages);
  });
});

app.post("/messages", async (req, res) => {
  try {
    var message = new Message(req.body);
    var savedMessage = await message.save();
    console.log("saved");

    var censored = await Message.findOne({ message: "badword" });

    if (censored) await Message.remove({ _id: censored.id });
    else io.emit("message", req.body);
    res.sendStatus(200);
  } catch (error) {
    res.sendStatus(500);
    return console.error(error);
  } finally {
    console.log("message post called");
  }
});

io.on("connection", socket => {
  console.log("a user has been connected");
});

mongoose.connect(
  dbUrl,
  { useNewUrlParser: true, useUnifiedTopology: true },
  err => {
    console.log("mongo db connection", err);
  }
);

var server = http.listen(2500, () => {
  console.log("server is listening on port", server.address().port);
});

Pilot the ObjectRocket Platform Free!

Try Fully-Managed CockroachDB, Elasticsearch, MongoDB, PostgreSQL (Beta) or Redis.

Get Started

Keep in the know!

Subscribe to our emails and we’ll let you know what’s going on at ObjectRocket. We hate spam and make it easy to unsubscribe.