Pibo Pibo - 4 months ago 49
Node.js Question

How to implement Express with mongoDb?

I'm building a web site in React, Redux, Express and Socket io using the starter of ErikRas: https://github.com/erikras/react-redux-universal-hot-example

It looks crazy to me: so many tutorials for react and redux. no want say how to implement MongoDb. I hope the answer will be useful for other people too. In fact, all the starters we can find on the web avoid to talk and give exemples about the data storage. ...Maybe because it pushes too far the complexity. I don't know. So... I'm trying to add MongoDb. The tutorials show different ways, but always with pure node.js and express, and often with an extremely easy setting. But the api of the starter isn't easy at all, and I got lost! I don't know if I have to connect it all in api.js, or server.js or... I'm extremely confuse!!!

I set up the MongoDb and it works fine. I already charged some data in it by the terminal.
Then, in the api.js I added some lines (commented in the following code):

import express from 'express';
import session from 'express-session';
import bodyParser from 'body-parser';
import config from '../src/config';
import * as actions from './actions/index';
import {mapUrl} from 'utils/url.js';
import PrettyError from 'pretty-error';
import http from 'http';
import SocketIo from 'socket.io';

// --------------- New Code
var mongo = require('mongodb');
var monk = require('monk');
var db = monk('localhost:27017/nodetest1');
// --------------------------------------

const pretty = new PrettyError();
const app = express();

const server = new http.Server(app);

const io = new SocketIo(server);
io.path('/ws');

app.use(session({
secret: 'react and redux rule!!!!',
resave: false,
saveUninitialized: false,
cookie: { maxAge: 60000 }
}));
app.use(bodyParser.json());

app.use((req, res) => {
const splittedUrlPath = req.url.split('?')[0].split('/').slice(1);

const {action, params} = mapUrl(actions, splittedUrlPath);

if (action) {
action(req, params)
.then((result) => {
if (result instanceof Function) {
result(res);
} else {
res.json(result);
}
}, (reason) => {
if (reason && reason.redirect) {
res.redirect(reason.redirect);
} else {
console.error('API ERROR:', pretty.render(reason));
res.status(reason.status || 500).json(reason);
}
});
} else {
res.status(404).end('NOT FOUND');
}
});

// -------------------> New code -> 'II part'
app.use(function(req,res,next){
req.db = db;
next();
});
// --------------------------------

const bufferSize = 100;
const messageBuffer = new Array(bufferSize);
let messageIndex = 0;

if (config.apiPort) {
const runnable = app.listen(config.apiPort, (err) => {
if (err) {
console.error(err);
}
console.info('----\n==>

Answer

So, here I come with a solution. I'll try to leave an answer as the one I would like to find.

For the moment, I just achieved to write in the Mongo Database. But a lot of work reste to do. And I'm not sure the way I use it is the best for the performance. So feel free to improve it and developpe a complete answer.

So, here how I did to use MongoDb with express and socket.io. I'm building my site from the boilerplate of Erik Ras

https://github.com/erikras/react-redux-universal-hot-example

Install MongoDb on your computer. It will install Mongo in C:\ I did it twice, the second time it was installed in Porgrams.

Create a new folder called "data" inside the folder called api.

Then navigate with the terminal inside the MongoDb folder and find bin. From there, digit the path to the data folder:

mongod --dbpath c:\nameofthefolderproject\api\data

Mongo initialize the data store (it takes a moment), starts and waits for connection.

Navigate with the terminal in the root of your project and installe mongoose:

npm install mongoose

Then open the file nameofthefolderproject\api\api.js There import mongoose:

import mongoose from 'mongoose';

and add right after the imports:

var mongoURI = "mongodb://localhost/nameofyourproject";
var db = mongoose.connect(mongoURI, function(err){
  if(err){
    console.log(err);
  }else{
    console.log('Finally connected!!!');
  }
});

You should recive the message in the terminal.

Create a folder in the api folder called: nameofthefolderproject\api\models

Inside create the file nameofthefolderproject\api\models\members.js

Create a mongoose schema. Look at the doc to understand it if you don't know it.

var mongoose = require('mongoose');

var membersSchema = mongoose.Schema({
    pseudo:{
        type: String,
        required: true
    },
    email:{
        type: String,
        required: true
    },
    date:{
        type: Date,
        default: Date.now
    }
});

var Members = module.exports = mongoose.model('members', membersSchema);

Create the file: nameofthefolderproject\api\models\index.js and write the following. Here you will collect all the models exporting everything ready to use.

export members from './members';

When the api calls the action, pass the models to the function.

app.use(bodyParser.json());

app.use((req, res) => {
  const splittedUrlPath = req.url.split('?')[0].split('/').slice(1);
  const {action, params} = mapUrl(actions, splittedUrlPath);
  // it calls the right action passing also the mongoose schemas (models)
  if (action) {
    action(req, params, models) etc etc...

Now go in the action called by the server. In my case: nameofthefolderproject\api\actions\addMember You can now use the model to register. In my case:

export default function addMember(req, err, models) {
   // this is the function called by the api. I passed all the models of mongoose.
  return new Promise((resolve, reject) => {
    // charge the data received from the form in a variable
    var data = req.body;
    // extract the mongoose model I interested about. 
    var Members = models.members;
    // initialise the mongoose schema and connect the data received to the schema
    var newMember = new Members({pseudo:data.pseudo, email:data.email});
    // In this way I can register the data in mongodb data store
    newMember.save(function(err, data){
        // verify if there is an error, and confirm eventually the success
         if(err){
            throw err;
            reject();
        }
        resolve();
    });
  });
}

If I'll have the time in next days I'll develop the rest and I post it.

Enjoy.

Max

Comments